handlebars-rust icon indicating copy to clipboard operation
handlebars-rust copied to clipboard

Supports `Result` for helper function

Open RoCry opened this issue 3 years ago • 4 comments

In production code the helpers may returns error, we could returns the underlying error from helper when render_template.

Below are some pseudo-code:

fn query_name_by_id(id: &str) -> Result<String, DBError> {
	...
}

let result = hbr.render_template("The name is {{query_name_by_id this}}", &id);

match result {
	Ok() -> {},
	Err(e) -> {
		match e {
			Handlebars.Error(e) => // render error
			DBError(e) => // db error from query_name_by_id
			_ => {}
		}
	}
}

RoCry avatar Jul 01 '22 08:07 RoCry

This is possible by down-casting error.source() to your own error type. I've made an example to demo this:

  1. Create RenderError from your own error type via RenderError::from_error: https://github.com/sunng87/handlebars-rust/blob/master/examples/error.rs#L20
  2. Down-casting the cause of render error for your own type: https://github.com/sunng87/handlebars-rust/blob/master/examples/error.rs#L78

sunng87 avatar Jul 02 '22 10:07 sunng87

The example answered my question. But it may be easier for me if:

  1. Change the handlebars_helper! to handlebars_helper_returns_result!
  2. Add a new handlebars_helper! based on 1 and keep the api exactly same with previous versions.

Is this make sense for you as well?

RoCry avatar Jul 05 '22 02:07 RoCry

For helper returning Result I would recommend to use impl HelperDef and implement call_inner directly: https://docs.rs/handlebars/latest/handlebars/trait.HelperDef.html#method.call_inner

I will add an example for this use case.

sunng87 avatar Jul 18 '22 06:07 sunng87

You can still reuse this as an example of defining helper with API that exposes the Result: https://github.com/sunng87/handlebars-rust/blob/master/examples/error.rs#L20

sunng87 avatar Jul 18 '22 07:07 sunng87