diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2022-04-16 16:12:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-16 16:12:26 +0200 |
commit | a87be28a46b67e53354f8ce69386057ddbb0f46c (patch) | |
tree | 5615afd3ac57821edd7c782cfe33d253777a8aa3 /cli/fmt_errors.rs | |
parent | 0bb96cde726127291dccb62145e76a50b2efcd2f (diff) |
feat: Better formatting for AggregateError (#14285)
This commit adds "aggregated" field to "deno_core::JsError" that stores
instances of "JsError" recursively to properly handle "AggregateError"
formatting. Appropriate logics was added to "PrettyJsError" and
"console" API to format AggregateErrors.
Co-authored-by: Nayeem Rahman <nayeemrmn99@gmail.com>
Diffstat (limited to 'cli/fmt_errors.rs')
-rw-r--r-- | cli/fmt_errors.rs | 97 |
1 files changed, 38 insertions, 59 deletions
diff --git a/cli/fmt_errors.rs b/cli/fmt_errors.rs index fb7ccdb86..953dfec8b 100644 --- a/cli/fmt_errors.rs +++ b/cli/fmt_errors.rs @@ -128,45 +128,6 @@ fn format_frame(frame: &JsStackFrame) -> String { result } -#[allow(clippy::too_many_arguments)] -fn format_stack( - is_error: bool, - message_line: &str, - cause: Option<&str>, - source_line: Option<&str>, - source_line_frame_index: Option<usize>, - frames: &[JsStackFrame], - level: usize, -) -> String { - let mut s = String::new(); - s.push_str(&format!("{:indent$}{}", "", message_line, indent = level)); - let column_number = - source_line_frame_index.and_then(|i| frames.get(i).unwrap().column_number); - s.push_str(&format_maybe_source_line( - source_line, - column_number, - is_error, - level, - )); - for frame in frames { - s.push_str(&format!( - "\n{:indent$} at {}", - "", - format_frame(frame), - indent = level - )); - } - if let Some(cause) = cause { - s.push_str(&format!( - "\n{:indent$}Caused by: {}", - "", - cause, - indent = level - )); - } - s -} - /// Take an optional source line and associated information to format it into /// a pretty printed version of that line. fn format_maybe_source_line( @@ -219,6 +180,43 @@ fn format_maybe_source_line( format!("\n{}{}\n{}{}", indent, source_line, indent, color_underline) } +fn format_js_error(js_error: &JsError, is_child: bool) -> String { + let mut s = String::new(); + s.push_str(&js_error.exception_message); + if let Some(aggregated) = &js_error.aggregated { + for aggregated_error in aggregated { + let error_string = format_js_error(aggregated_error, true); + for line in error_string.trim_start_matches("Uncaught ").lines() { + s.push_str(&format!("\n {}", line)); + } + } + } + let column_number = js_error + .source_line_frame_index + .and_then(|i| js_error.frames.get(i).unwrap().column_number); + s.push_str(&format_maybe_source_line( + if is_child { + None + } else { + js_error.source_line.as_deref() + }, + column_number, + true, + 0, + )); + for frame in &js_error.frames { + s.push_str(&format!("\n at {}", format_frame(frame))); + } + if let Some(cause) = &js_error.cause { + let error_string = format_js_error(cause, true); + s.push_str(&format!( + "\nCaused by: {}", + error_string.trim_start_matches("Uncaught ") + )); + } + s +} + /// Wrapper around deno_core::JsError which provides colorful /// string representation. #[derive(Debug)] @@ -240,26 +238,7 @@ impl Deref for PrettyJsError { impl fmt::Display for PrettyJsError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let cause = self - .0 - .cause - .clone() - .map(|cause| format!("{}", PrettyJsError(*cause))); - - write!( - f, - "{}", - &format_stack( - true, - &self.0.exception_message, - cause.as_deref(), - self.0.source_line.as_deref(), - self.0.source_line_frame_index, - &self.0.frames, - 0 - ) - )?; - Ok(()) + write!(f, "{}", &format_js_error(&self.0, false)) } } |