From f1fd1d8071b6423dc756915eff5eca0714f10f7a Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sat, 4 May 2024 17:02:14 +0900 Subject: [PATCH] cli: show hint for inner fileset/revset/template errors Note that find_source_parse_error_hint() has recursion, but it should terminate because err.source() shouldn't have a cycle. --- cli/src/command_error.rs | 10 ++++++++++ cli/tests/test_commit_template.rs | 32 +++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cli/src/command_error.rs b/cli/src/command_error.rs index d30de4fa1..a95506700 100644 --- a/cli/src/command_error.rs +++ b/cli/src/command_error.rs @@ -516,8 +516,18 @@ fn find_source_parse_error_hint(err: &dyn error::Error) -> Option { let source = err.source()?; if let Some(source) = source.downcast_ref() { file_pattern_parse_error_hint(source) + } else if let Some(source) = source.downcast_ref() { + fileset_parse_error_hint(source) + } else if let Some(source) = source.downcast_ref() { + revset_parse_error_hint(source) + } else if let Some(source) = source.downcast_ref() { + revset_resolution_error_hint(source) + } else if let Some(UserRevsetEvaluationError::Resolution(source)) = source.downcast_ref() { + revset_resolution_error_hint(source) } else if let Some(source) = source.downcast_ref() { string_pattern_parse_error_hint(source) + } else if let Some(source) = source.downcast_ref() { + template_parse_error_hint(source) } else { None } diff --git a/cli/tests/test_commit_template.rs b/cli/tests/test_commit_template.rs index 0e0363ee4..65e87afb9 100644 --- a/cli/tests/test_commit_template.rs +++ b/cli/tests/test_commit_template.rs @@ -742,17 +742,41 @@ fn test_log_contained_in() { let stderr = test_env.jj_cmd_failure( &repo_path, - &["log", "-r::", "-T", &template_for_revset("unknown_symbol")], + &["log", "-r::", "-T", &template_for_revset("author(x:'y')")], + ); + insta::assert_snapshot!(stderr, @r###" + Error: Failed to parse template: Failed to parse revset + Caused by: + 1: --> 5:28 + | + 5 | if(self.contained_in("author(x:'y')"), "[contained_in]"), + | ^-------------^ + | + = Failed to parse revset + 2: --> 1:8 + | + 1 | author(x:'y') + | ^---^ + | + = Function "author": Invalid string pattern + 3: Invalid string pattern kind "x:" + Hint: Try prefixing with one of `exact:`, `glob:` or `substring:` + "###); + + let stderr = test_env.jj_cmd_failure( + &repo_path, + &["log", "-r::", "-T", &template_for_revset("maine")], ); insta::assert_snapshot!(stderr, @r###" Error: Failed to parse template: Failed to evaluate revset Caused by: 1: --> 5:28 | - 5 | if(self.contained_in("unknown_symbol"), "[contained_in]"), - | ^--------------^ + 5 | if(self.contained_in("maine"), "[contained_in]"), + | ^-----^ | = Failed to evaluate revset - 2: Revision "unknown_symbol" doesn't exist + 2: Revision "maine" doesn't exist + Hint: Did you mean "main"? "###); }