From ac7d9e8031b4df489a0d58dc3459bc931f1ff870 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 2 Nov 2020 14:26:17 +0100 Subject: Improve error handling (see #368) --- askama_shared/src/parser.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'askama_shared/src/parser.rs') diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index 908ae55..9344c07 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -8,7 +8,7 @@ use nom::sequence::{delimited, pair, tuple}; use nom::{self, error_position, Compare, IResult, InputTake}; use std::str; -use crate::Syntax; +use crate::{CompileError, Syntax}; #[derive(Debug, PartialEq)] pub enum Node<'a> { @@ -186,7 +186,7 @@ fn take_content<'a>(i: &'a [u8], s: &'a Syntax<'a>) -> ParserError<'a, Node<'a>> Any } } - End(_) => panic!("cannot happen"), + End(_) => unreachable!(), }; if let End(_) = state { break; @@ -1056,19 +1056,23 @@ fn tag_expr_end<'a>(i: &'a [u8], s: &'a Syntax<'a>) -> IResult<&'a [u8], &'a [u8 tag(s.expr_end)(i) } -pub fn parse<'a>(src: &'a str, syntax: &'a Syntax<'a>) -> Vec> { +pub fn parse<'a>(src: &'a str, syntax: &'a Syntax<'a>) -> Result>, CompileError> { match parse_template(src.as_bytes(), syntax) { Ok((left, res)) => { if !left.is_empty() { let s = str::from_utf8(left).unwrap(); - panic!("unable to parse template:\n\n{:?}", s); + Err(format!("unable to parse template:\n\n{:?}", s).into()) } else { - res + Ok(res) } } - Err(nom::Err::Error(err)) => panic!("problems parsing template source: {:?}", err), - Err(nom::Err::Failure(err)) => panic!("problems parsing template source: {:?}", err), - Err(nom::Err::Incomplete(_)) => panic!("parsing incomplete"), + Err(nom::Err::Error(err)) => { + Err(format!("problems parsing template source: {:?}", err).into()) + } + Err(nom::Err::Failure(err)) => { + Err(format!("problems parsing template source: {:?}", err).into()) + } + Err(nom::Err::Incomplete(_)) => Err("parsing incomplete".into()), } } @@ -1102,18 +1106,18 @@ mod tests { #[test] #[should_panic] fn test_invalid_block() { - super::parse("{% extend \"blah\" %}", &Syntax::default()); + super::parse("{% extend \"blah\" %}", &Syntax::default()).unwrap(); } #[test] fn test_parse_filter() { - super::parse("{{ strvar|e }}", &Syntax::default()); + super::parse("{{ strvar|e }}", &Syntax::default()).unwrap(); } #[test] fn test_parse_var_call() { assert_eq!( - super::parse("{{ function(\"123\", 3) }}", &Syntax::default()), + super::parse("{{ function(\"123\", 3) }}", &Syntax::default()).unwrap(), vec![super::Node::Expr( super::WS(false, false), super::Expr::VarCall( @@ -1127,7 +1131,7 @@ mod tests { #[test] fn test_parse_path_call() { assert_eq!( - super::parse("{{ self::function(\"123\", 3) }}", &Syntax::default()), + super::parse("{{ self::function(\"123\", 3) }}", &Syntax::default()).unwrap(), vec![super::Node::Expr( super::WS(false, false), super::Expr::PathCall( @@ -1146,7 +1150,7 @@ mod tests { ..Syntax::default() }; - super::parse("{~ strvar|e ~}", &syntax); + super::parse("{~ strvar|e ~}", &syntax).unwrap(); } } -- cgit