diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-09-22 23:30:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-22 23:30:03 +0200 |
commit | 68fd7a927b26c3e72cf73515821450f3aa252014 (patch) | |
tree | 61536703a37c1584eef8f69f954418a68f9533f8 /core/error.rs | |
parent | cf0c49191e9be862027f74f39318a3479fce3ba2 (diff) |
refactor(core): support error stack, remove js_check (#7629)
This commit adds support for stack traces in "deno_core".
Implementation of "Display" trait for "JsError" has been updated
and in consequence "deno_core::js_check" became obsolete and
removed.
Diffstat (limited to 'core/error.rs')
-rw-r--r-- | core/error.rs | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/core/error.rs b/core/error.rs index 25a7ec12b..1aa67e26c 100644 --- a/core/error.rs +++ b/core/error.rs @@ -97,6 +97,7 @@ pub struct JsError { pub start_column: Option<i64>, // 0-based pub end_column: Option<i64>, // 0-based pub frames: Vec<JsStackFrame>, + pub stack: Option<String>, } #[derive(Debug, PartialEq, Clone)] @@ -166,7 +167,7 @@ impl JsError { let msg = v8::Exception::create_message(scope, exception); - let (message, frames) = if exception.is_native_error() { + let (message, frames, stack) = if exception.is_native_error() { // The exception is a JS Error object. let exception: v8::Local<v8::Object> = exception.clone().try_into().unwrap(); @@ -184,7 +185,14 @@ impl JsError { // Access error.stack to ensure that prepareStackTrace() has been called. // This should populate error.__callSiteEvals. - let _ = get_property(scope, exception, "stack"); + let stack: Option<v8::Local<v8::String>> = + get_property(scope, exception, "stack") + .unwrap() + .try_into() + .ok(); + let stack = stack.map(|s| s.to_rust_string_lossy(scope)); + + // FIXME(bartlmieju): the rest of this function is CLI only // Read an array of structured frames from error.__callSiteEvals. let frames_v8 = get_property(scope, exception, "__callSiteEvals"); @@ -300,12 +308,12 @@ impl JsError { }); } } - (message, frames) + (message, frames, stack) } else { // The exception is not a JS Error object. // Get the message given by V8::Exception::create_message(), and provide // empty frames. - (msg.get(scope).to_rust_string_lossy(scope), vec![]) + (msg.get(scope).to_rust_string_lossy(scope), vec![], None) }; Self { @@ -321,6 +329,7 @@ impl JsError { start_column: msg.get_start_column().try_into().ok(), end_column: msg.get_end_column().try_into().ok(), frames, + stack, } } } @@ -339,35 +348,24 @@ fn format_source_loc( impl Display for JsError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { + if let Some(stack) = &self.stack { + let stack_lines = stack.lines(); + if stack_lines.count() > 1 { + return writeln!(f, "{}", stack); + } + } + + writeln!(f, "{}", self.message)?; if let Some(script_resource_name) = &self.script_resource_name { if self.line_number.is_some() && self.start_column.is_some() { - assert!(self.line_number.is_some()); - assert!(self.start_column.is_some()); let source_loc = format_source_loc( script_resource_name, self.line_number.unwrap(), self.start_column.unwrap(), ); - write!(f, "{}", source_loc)?; - } - if self.source_line.is_some() { - let source_line = self.source_line.as_ref().unwrap(); - write!(f, "\n{}\n", source_line)?; - let mut s = String::new(); - for i in 0..self.end_column.unwrap() { - if i >= self.start_column.unwrap() { - s.push('^'); - } else if source_line.chars().nth(i as usize).unwrap() == '\t' { - s.push('\t'); - } else { - s.push(' '); - } - } - writeln!(f, "{}", s)?; + writeln!(f, " at {}", source_loc)?; } } - - write!(f, "{}", self.message)?; Ok(()) } } |