Struct handlebars::RenderError

source ·
pub struct RenderError {
    pub desc: String,
    pub template_name: Option<String>,
    pub line_no: Option<usize>,
    pub column_no: Option<usize>,
    /* private fields */
}
Expand description

Error when rendering data on template.

Fields§

§desc: String§template_name: Option<String>§line_no: Option<usize>§column_no: Option<usize>

Implementations§

Examples found in repository?
src/error.rs (line 109)
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    pub fn strict_error(path: Option<&String>) -> RenderError {
        let msg = match path {
            Some(path) => format!("Variable {:?} not found in strict mode.", path),
            None => "Value is missing in strict mode".to_owned(),
        };
        RenderError::new(&msg)
    }

    pub fn from_error<E>(error_info: &str, cause: E) -> RenderError
    where
        E: StdError + Send + Sync + 'static,
    {
        let mut e = RenderError::new(error_info);
        e.cause = Some(Box::new(cause));

        e
    }
More examples
Hide additional examples
src/registry.rs (line 524)
517
518
519
520
521
522
523
524
525
526
    pub(crate) fn get_or_load_template(
        &'reg self,
        name: &str,
    ) -> Result<Cow<'reg, Template>, RenderError> {
        if let Some(result) = self.get_or_load_template_optional(name) {
            result
        } else {
            Err(RenderError::new(format!("Template not found: {}", name)))
        }
    }
src/decorators/inline.rs (line 12)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
fn get_name<'reg: 'rc, 'rc>(d: &Decorator<'reg, 'rc>) -> Result<String, RenderError> {
    d.param(0)
        .ok_or_else(|| RenderError::new("Param required for decorator \"inline\""))
        .and_then(|v| {
            v.value()
                .as_str()
                .map(|v| v.to_owned())
                .ok_or_else(|| RenderError::new("inline name must be string"))
        })
}

impl DecoratorDef for InlineDecorator {
    fn call<'reg: 'rc, 'rc>(
        &self,
        d: &Decorator<'reg, 'rc>,
        _: &'reg Registry<'reg>,
        _: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
    ) -> DecoratorResult {
        let name = get_name(d)?;

        let template = d
            .template()
            .ok_or_else(|| RenderError::new("inline should have a block"))?;

        rc.set_partial(name, template);
        Ok(())
    }
src/json/path.rs (line 41)
34
35
36
37
38
39
40
41
42
    pub fn parse(raw: &str) -> Result<Path, RenderError> {
        HandlebarsParser::parse(Rule::path, raw)
            .map(|p| {
                let parsed = p.flatten();
                let segs = parse_json_path_from_iter(&mut parsed.peekable(), raw.len());
                Ok(Path::new(raw, segs))
            })
            .map_err(|_| RenderError::new("Invalid JSON path"))?
    }
src/helpers/helper_if.rs (line 25)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> HelperResult {
        let param = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"if\""))?;
        let include_zero = h
            .hash_get("includeZero")
            .and_then(|v| v.value().as_bool())
            .unwrap_or(false);

        let mut value = param.value().is_truthy(include_zero);

        if !self.positive {
            value = !value;
        }

        let tmpl = if value { h.template() } else { h.inverse() };
        match tmpl {
            Some(t) => t.render(r, ctx, rc, out),
            None => Ok(()),
        }
    }
src/helpers/helper_log.rs (lines 49-52)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        _: &'reg Registry<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
        _: &mut dyn Output,
    ) -> HelperResult {
        let param_to_log = h
            .params()
            .iter()
            .map(|p| {
                if let Some(ref relative_path) = p.relative_path() {
                    format!("{}: {}", relative_path, p.value().render())
                } else {
                    p.value().render()
                }
            })
            .collect::<Vec<String>>()
            .join(", ");

        let level = h
            .hash_get("level")
            .and_then(|v| v.value().as_str())
            .unwrap_or("info");

        if let Ok(log_level) = Level::from_str(level) {
            log!(log_level, "{}", param_to_log)
        } else {
            return Err(RenderError::new(&format!(
                "Unsupported logging level {}",
                level
            )));
        }
        Ok(())
    }
Examples found in repository?
src/helpers/mod.rs (line 125)
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> HelperResult {
        match self.call_inner(h, r, ctx, rc) {
            Ok(result) => {
                if r.strict_mode() && result.is_missing() {
                    Err(RenderError::strict_error(None))
                } else {
                    // auto escape according to settings
                    let output = do_escape(r, rc, result.render());
                    out.write(output.as_ref())?;
                    Ok(())
                }
            }
            Err(e) => {
                if e.is_unimplemented() {
                    // default implementation, do nothing
                    Ok(())
                } else {
                    Err(e)
                }
            }
        }
    }
More examples
Hide additional examples
src/helpers/helper_lookup.rs (line 42)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    fn call_inner<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        _: &'rc Context,
        _: &mut RenderContext<'reg, 'rc>,
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError> {
        let collection_value = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"lookup\""))?;
        let index = h
            .param(1)
            .ok_or_else(|| RenderError::new("Insufficient params for helper \"lookup\""))?;

        let value = match *collection_value.value() {
            Json::Array(ref v) => index
                .value()
                .as_u64()
                .and_then(|u| v.get(u as usize))
                .unwrap_or(&Json::Null),
            Json::Object(ref m) => index
                .value()
                .as_str()
                .and_then(|k| m.get(k))
                .unwrap_or(&Json::Null),
            _ => &Json::Null,
        };
        if r.strict_mode() && value.is_null() {
            Err(RenderError::strict_error(None))
        } else {
            Ok(value.clone().into())
        }
    }
src/helpers/helper_with.rs (line 52)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> HelperResult {
        let param = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"with\""))?;

        if param.value().is_truthy(false) {
            let mut block = create_block(param);

            if let Some(block_param) = h.block_param() {
                let mut params = BlockParams::new();
                if param.context_path().is_some() {
                    params.add_path(block_param, Vec::with_capacity(0))?;
                } else {
                    params.add_value(block_param, param.value().clone())?;
                }

                block.set_block_params(params);
            }

            rc.push_block(block);

            if let Some(t) = h.template() {
                t.render(r, ctx, rc, out)?;
            };

            rc.pop_block();
            Ok(())
        } else if let Some(t) = h.inverse() {
            t.render(r, ctx, rc, out)
        } else if r.strict_mode() {
            Err(RenderError::strict_error(param.relative_path()))
        } else {
            Ok(())
        }
    }
src/render.rs (line 815)
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
    fn render<'reg: 'rc, 'rc>(
        &'reg self,
        registry: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> Result<(), RenderError> {
        match self {
            RawString(ref v) => indent_aware_write(v.as_ref(), rc, out),
            Expression(ref ht) | HtmlExpression(ref ht) => {
                let is_html_expression = matches!(self, HtmlExpression(_));
                if is_html_expression {
                    rc.set_disable_escape(true);
                }

                // test if the expression is to render some value
                let result = if ht.is_name_only() {
                    let helper_name = ht.name.expand_as_name(registry, ctx, rc)?;
                    if helper_exists(&helper_name, registry, rc) {
                        render_helper(ht, registry, ctx, rc, out)
                    } else {
                        debug!("Rendering value: {:?}", ht.name);
                        let context_json = ht.name.expand(registry, ctx, rc)?;
                        if context_json.is_value_missing() {
                            if registry.strict_mode() {
                                Err(RenderError::strict_error(context_json.relative_path()))
                            } else {
                                // helper missing
                                if let Some(hook) = registry.get_or_load_helper(HELPER_MISSING)? {
                                    let h = Helper::try_from_template(ht, registry, ctx, rc)?;
                                    hook.call(&h, registry, ctx, rc, out)
                                } else {
                                    Ok(())
                                }
                            }
                        } else {
                            let rendered = context_json.value().render();
                            let output = do_escape(registry, rc, rendered);
                            indent_aware_write(output.as_ref(), rc, out)
                        }
                    }
                } else {
                    // this is a helper expression
                    render_helper(ht, registry, ctx, rc, out)
                };

                if is_html_expression {
                    rc.set_disable_escape(false);
                }

                result
            }
            HelperBlock(ref ht) => render_helper(ht, registry, ctx, rc, out),
            DecoratorExpression(_) | DecoratorBlock(_) => self.eval(registry, ctx, rc),
            PartialExpression(ref dt) | PartialBlock(ref dt) => {
                let di = Decorator::try_from_template(dt, registry, ctx, rc)?;

                partial::expand_partial(&di, registry, ctx, rc, out)
            }
            _ => Ok(()),
        }
    }
src/helpers/helper_each.rs (line 147)
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    fn call<'reg: 'rc, 'rc>(
        &self,
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output,
    ) -> HelperResult {
        let value = h
            .param(0)
            .ok_or_else(|| RenderError::new("Param not found for helper \"each\""))?;

        let template = h.template();

        match template {
            Some(t) => match *value.value() {
                Json::Array(ref list)
                    if !list.is_empty() || (list.is_empty() && h.inverse().is_none()) =>
                {
                    let block_context = create_block(value);
                    rc.push_block(block_context);

                    let len = list.len();

                    let array_path = value.context_path();

                    for (i, v) in list.iter().enumerate().take(len) {
                        if let Some(ref mut block) = rc.block_mut() {
                            let is_first = i == 0usize;
                            let is_last = i == len - 1;

                            let index = to_json(i);
                            block.set_local_var("first", to_json(is_first));
                            block.set_local_var("last", to_json(is_last));
                            block.set_local_var("index", index.clone());

                            update_block_context(block, array_path, i.to_string(), is_first, v);
                            set_block_param(block, h, array_path, &index, v)?;
                        }

                        t.render(r, ctx, rc, out)?;
                    }

                    rc.pop_block();
                    Ok(())
                }
                Json::Object(ref obj)
                    if !obj.is_empty() || (obj.is_empty() && h.inverse().is_none()) =>
                {
                    let block_context = create_block(value);
                    rc.push_block(block_context);

                    let len = obj.len();

                    let obj_path = value.context_path();

                    for (i, (k, v)) in obj.iter().enumerate() {
                        if let Some(ref mut block) = rc.block_mut() {
                            let is_first = i == 0usize;
                            let is_last = i == len - 1;

                            let key = to_json(k);
                            block.set_local_var("first", to_json(is_first));
                            block.set_local_var("last", to_json(is_last));
                            block.set_local_var("key", key.clone());

                            update_block_context(block, obj_path, k.to_string(), is_first, v);
                            set_block_param(block, h, obj_path, &key, v)?;
                        }

                        t.render(r, ctx, rc, out)?;
                    }

                    rc.pop_block();
                    Ok(())
                }
                _ => {
                    if let Some(else_template) = h.inverse() {
                        else_template.render(r, ctx, rc, out)
                    } else if r.strict_mode() {
                        Err(RenderError::strict_error(value.relative_path()))
                    } else {
                        Ok(())
                    }
                }
            },
            None => Ok(()),
        }
    }
Examples found in repository?
src/error.rs (line 47)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    fn from(e: IOError) -> RenderError {
        RenderError::from_error("Cannot generate output.", e)
    }
}

impl From<SerdeError> for RenderError {
    fn from(e: SerdeError) -> RenderError {
        RenderError::from_error("Failed to access JSON data.", e)
    }
}

impl From<FromUtf8Error> for RenderError {
    fn from(e: FromUtf8Error) -> RenderError {
        RenderError::from_error("Failed to generate bytes.", e)
    }
}

impl From<ParseIntError> for RenderError {
    fn from(e: ParseIntError) -> RenderError {
        RenderError::from_error("Cannot access array/vector with string index.", e)
    }
}

impl From<TemplateError> for RenderError {
    fn from(e: TemplateError) -> RenderError {
        RenderError::from_error("Failed to parse template.", e)
    }
}

#[cfg(feature = "script_helper")]
impl From<Box<EvalAltResult>> for RenderError {
    fn from(e: Box<EvalAltResult>) -> RenderError {
        RenderError::from_error("Cannot convert data to Rhai dynamic", e)
    }
}

#[cfg(feature = "script_helper")]
impl From<ScriptError> for RenderError {
    fn from(e: ScriptError) -> RenderError {
        RenderError::from_error("Failed to load rhai script", e)
    }

Trait Implementations§

Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Formats the value using the given formatter. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to provide by using demand. Read more
Should always be Self
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.