summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2020-04-20 20:39:02 +0100
committerGitHub <noreply@github.com>2020-04-20 15:39:02 -0400
commitef6ee25e09c902e1f9d89a40cf05660432e7143c (patch)
treeb43745fa471693e7d8787b4a5e9a2489f895c873
parentf72f045de586a7d0e428b77f6a3e381178cc6674 (diff)
refactor(cli/fmt_errors): Improve source line formatting (#4832)
-rw-r--r--cli/diagnostics.rs187
-rw-r--r--cli/fmt_errors.rs201
-rw-r--r--cli/tests/038_checkjs.js.out24
-rw-r--r--cli/tests/044_bad_resource.ts.out4
-rw-r--r--cli/tests/async_error.ts.out7
-rw-r--r--cli/tests/config.ts.out11
-rw-r--r--cli/tests/error_001.ts.out7
-rw-r--r--cli/tests/error_002.ts.out7
-rw-r--r--cli/tests/error_003_typescript.ts.out9
-rw-r--r--cli/tests/error_004_missing_module.ts.out1
-rw-r--r--cli/tests/error_005_missing_dynamic_import.ts.out1
-rw-r--r--cli/tests/error_006_import_ext_failure.ts.out1
-rw-r--r--cli/tests/error_008_checkjs.js.out7
-rw-r--r--cli/tests/error_011_bad_module_specifier.ts.out1
-rw-r--r--cli/tests/error_012_bad_dynamic_import_specifier.ts.out1
-rw-r--r--cli/tests/error_017_hide_long_source_ts.ts.out3
-rw-r--r--cli/tests/error_018_hide_long_source_js.js.out1
-rw-r--r--cli/tests/error_syntax.js.out8
-rw-r--r--cli/tests/error_syntax_empty_trailing_line.mjs.out2
-rw-r--r--cli/tests/error_type_definitions.ts.out1
-rw-r--r--core/js_errors.rs7
21 files changed, 219 insertions, 272 deletions
diff --git a/cli/diagnostics.rs b/cli/diagnostics.rs
index b0b284360..aca86913e 100644
--- a/cli/diagnostics.rs
+++ b/cli/diagnostics.rs
@@ -6,9 +6,7 @@
// serde_json.
use crate::colors;
-use crate::fmt_errors::format_maybe_source_line;
-use crate::fmt_errors::format_maybe_source_name;
-use crate::fmt_errors::DisplayFormatter;
+use crate::fmt_errors::format_stack;
use serde_json::value::Value;
use std::error::Error;
use std::fmt;
@@ -56,14 +54,14 @@ impl fmt::Display for Diagnostic {
let mut i = 0;
for item in &self.items {
if i > 0 {
- writeln!(f)?;
+ write!(f, "\n\n")?;
}
write!(f, "{}", item.to_string())?;
i += 1;
}
if i > 1 {
- write!(f, "\n\nFound {} errors.\n", i)?;
+ write!(f, "\n\nFound {} errors.", i)?;
}
Ok(())
@@ -181,91 +179,126 @@ impl DiagnosticItem {
}
}
-impl DisplayFormatter for DiagnosticItem {
- fn format_category_and_code(&self) -> String {
- let category = match self.category {
- DiagnosticCategory::Error => {
- format!("{}", colors::red_bold("error".to_string()))
- }
- DiagnosticCategory::Warning => "warn".to_string(),
- DiagnosticCategory::Debug => "debug".to_string(),
- DiagnosticCategory::Info => "info".to_string(),
- _ => "".to_string(),
- };
+fn format_category_and_code(
+ category: &DiagnosticCategory,
+ code: i64,
+) -> String {
+ let category = match category {
+ DiagnosticCategory::Error => {
+ format!("{}", colors::red_bold("error".to_string()))
+ }
+ DiagnosticCategory::Warning => "warn".to_string(),
+ DiagnosticCategory::Debug => "debug".to_string(),
+ DiagnosticCategory::Info => "info".to_string(),
+ _ => "".to_string(),
+ };
- let code =
- colors::bold(format!(" TS{}", self.code.to_string())).to_string();
+ let code = colors::bold(format!("TS{}", code.to_string())).to_string();
- format!("{}{}: ", category, code)
+ format!("{} {}", category, code)
+}
+
+fn format_message(
+ message_chain: &Option<DiagnosticMessageChain>,
+ message: &str,
+ level: usize,
+) -> String {
+ debug!("format_message");
+ if message_chain.is_none() {
+ return format!("{:indent$}{}", "", message, indent = level);
}
- fn format_message(&self, level: usize) -> String {
- debug!("format_message");
- if self.message_chain.is_none() {
- return format!("{:indent$}{}", "", self.message, indent = level);
- }
+ let mut s = message_chain.clone().unwrap().format_message(level);
+ s.pop();
- let mut s = self.message_chain.clone().unwrap().format_message(level);
- s.pop();
+ s
+}
- s
+/// Formats optional source, line and column numbers into a single string.
+fn format_maybe_frame(
+ file_name: Option<String>,
+ line_number: Option<i64>,
+ column_number: Option<i64>,
+) -> String {
+ if file_name.is_none() {
+ return "".to_string();
}
- fn format_related_info(&self) -> String {
- if self.related_information.is_none() {
- return "".to_string();
- }
+ assert!(line_number.is_some());
+ assert!(column_number.is_some());
- let mut s = String::new();
- let related_information = self.related_information.clone().unwrap();
- for related_diagnostic in related_information {
- let rd = &related_diagnostic;
- s.push_str(&format!(
- "\n{}\n\n ► {}{}\n",
- rd.format_message(2),
- rd.format_source_name(),
- rd.format_source_line(4),
- ));
- }
+ let line_number = line_number.unwrap();
+ let column_number = column_number.unwrap();
+ let file_name_c = colors::cyan(file_name.unwrap());
+ let line_c = colors::yellow(line_number.to_string());
+ let column_c = colors::yellow(column_number.to_string());
+ format!("{}:{}:{}", file_name_c, line_c, column_c)
+}
- s
+fn format_maybe_related_information(
+ related_information: &Option<Vec<DiagnosticItem>>,
+) -> String {
+ if related_information.is_none() {
+ return "".to_string();
}
- fn format_source_line(&self, level: usize) -> String {
- // Formatter expects 1-based line numbers, but ours are 0-based.
- format_maybe_source_line(
- self.source_line.clone(),
- self.line_number.map(|n| n + 1),
- self.start_column,
- self.end_column,
- match self.category {
+ let mut s = String::new();
+ let related_information = related_information.clone().unwrap();
+ for rd in related_information {
+ s.push_str("\n\n");
+ s.push_str(&format_stack(
+ match rd.category {
DiagnosticCategory::Error => true,
_ => false,
},
- level,
- )
+ format_message(&rd.message_chain, &rd.message, 0),
+ rd.source_line.clone(),
+ rd.start_column,
+ rd.end_column,
+ // Formatter expects 1-based line and column numbers, but ours are 0-based.
+ &[format_maybe_frame(
+ rd.script_resource_name.clone(),
+ rd.line_number.map(|n| n + 1),
+ rd.start_column.map(|n| n + 1),
+ )],
+ 4,
+ ));
}
- fn format_source_name(&self) -> String {
- // Formatter expects 1-based line and column numbers, but ours are 0-based.
- format_maybe_source_name(
- self.script_resource_name.clone(),
- self.line_number.map(|n| n + 1),
- self.start_column.map(|n| n + 1),
- )
- }
+ s
}
impl fmt::Display for DiagnosticItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
- "{}{}\n\n► {}{}{}",
- self.format_category_and_code(),
- self.format_message(0),
- self.format_source_name(),
- self.format_source_line(0),
- self.format_related_info(),
+ "{}",
+ format_stack(
+ match self.category {
+ DiagnosticCategory::Error => true,
+ _ => false,
+ },
+ format!(
+ "{}: {}",
+ format_category_and_code(&self.category, self.code),
+ format_message(&self.message_chain, &self.message, 0)
+ ),
+ self.source_line.clone(),
+ self.start_column,
+ self.end_column,
+ // Formatter expects 1-based line and column numbers, but ours are 0-based.
+ &[format_maybe_frame(
+ self.script_resource_name.clone(),
+ self.line_number.map(|n| n + 1),
+ self.start_column.map(|n| n + 1)
+ )],
+ 0
+ )
+ )?;
+ write!(
+ f,
+ "{}",
+ format_maybe_related_information(&self.related_information),
)
}
}
@@ -575,14 +608,30 @@ mod tests {
#[test]
fn diagnostic_to_string1() {
let d = diagnostic1();
- let expected = "error TS2322: Type \'(o: T) => { v: any; f: (x: B) => string; }[]\' is not assignable to type \'(r: B) => Value<B>[]\'.\n Types of parameters \'o\' and \'r\' are incompatible.\n Type \'B\' is not assignable to type \'T\'.\n\n► deno/tests/complex_diagnostics.ts:19:3\n\n19 values: o => [\n ~~~~~~\n\n The expected type comes from property \'values\' which is declared here on type \'SettingsInterface<B>\'\n\n ► deno/tests/complex_diagnostics.ts:7:3\n\n 7 values?: (r: T) => Array<Value<T>>;\n ~~~~~~\n\n";
+ let expected = "error TS2322: Type \'(o: T) => { v: any; f: (x: B) => string; }[]\' is not assignable to type \'(r: B) => Value<B>[]\'.\n Types of parameters \'o\' and \'r\' are incompatible.\n Type \'B\' is not assignable to type \'T\'.\n values: o => [\n ~~~~~~\n at deno/tests/complex_diagnostics.ts:19:3\n\n The expected type comes from property \'values\' which is declared here on type \'SettingsInterface<B>\'\n values?: (r: T) => Array<Value<T>>;\n ~~~~~~\n at deno/tests/complex_diagnostics.ts:7:3";
assert_eq!(expected, strip_ansi_codes(&d.to_string()));
}
#[test]
fn diagnostic_to_string2() {
let d = diagnostic2();
- let expected = "error TS2322: Example 1\n\n► deno/tests/complex_diagnostics.ts:19:3\n\n19 values: o => [\n ~~~~~~\n\nerror TS2000: Example 2\n\n► /foo/bar.ts:129:3\n\n129 values: undefined,\n ~~~~~~\n\n\nFound 2 errors.\n";
+ let expected = "error TS2322: Example 1\n values: o => [\n ~~~~~~\n at deno/tests/complex_diagnostics.ts:19:3\n\nerror TS2000: Example 2\n values: undefined,\n ~~~~~~\n at /foo/bar.ts:129:3\n\nFound 2 errors.";
assert_eq!(expected, strip_ansi_codes(&d.to_string()));
}
+
+ #[test]
+ fn test_format_none_frame() {
+ let actual = format_maybe_frame(None, None, None);
+ assert_eq!(actual, "");
+ }
+
+ #[test]
+ fn test_format_some_frame() {
+ let actual = format_maybe_frame(
+ Some("file://foo/bar.ts".to_string()),
+ Some(1),
+ Some(2),
+ );
+ assert_eq!(strip_ansi_codes(&actual), "file://foo/bar.ts:1:2");
+ }
}
diff --git a/cli/fmt_errors.rs b/cli/fmt_errors.rs
index 19e6616ca..d2c69819f 100644
--- a/cli/fmt_errors.rs
+++ b/cli/fmt_errors.rs
@@ -10,63 +10,49 @@ use std::ops::Deref;
const SOURCE_ABBREV_THRESHOLD: usize = 150;
-/// A trait which specifies parts of a diagnostic like item needs to be able to
-/// generate to conform its display to other diagnostic like items
-pub trait DisplayFormatter {
- fn format_category_and_code(&self) -> String;
- fn format_message(&self, level: usize) -> String;
- fn format_related_info(&self) -> String;
- fn format_source_line(&self, level: usize) -> String;
- fn format_source_name(&self) -> String;
-}
-
-fn format_source_name(
- file_name: String,
- line_number: i64,
- column_number: i64,
-) -> String {
- let line_number = line_number;
- let column_number = column_number;
- let file_name_c = colors::cyan(file_name);
- let line_c = colors::yellow(line_number.to_string());
- let column_c = colors::yellow(column_number.to_string());
- format!("{}:{}:{}", file_name_c, line_c, column_c)
-}
-
-/// Formats optional source, line and column numbers into a single string.
-pub fn format_maybe_source_name(
- file_name: Option<String>,
- line_number: Option<i64>,
- column_number: Option<i64>,
+pub fn format_stack(
+ is_error: bool,
+ message_line: String,
+ source_line: Option<String>,
+ start_column: Option<i64>,
+ end_column: Option<i64>,
+ formatted_frames: &[String],
+ level: usize,
) -> String {
- if file_name.is_none() {
- return "".to_string();
- }
-
- assert!(line_number.is_some());
- assert!(column_number.is_some());
- format_source_name(
- file_name.unwrap(),
- line_number.unwrap(),
- column_number.unwrap(),
- )
+ let mut s = String::new();
+ s.push_str(&format!("{:indent$}{}", "", message_line, indent = level));
+ s.push_str(&format_maybe_source_line(
+ source_line,
+ start_column,
+ end_column,
+ is_error,
+ level,
+ ));
+ for formatted_frame in formatted_frames {
+ s.push_str(&format!(
+ "\n{:indent$} at {}",
+ "",
+ formatted_frame,
+ indent = level
+ ));
+ }
+ s
}
/// Take an optional source line and associated information to format it into
/// a pretty printed version of that line.
-pub fn format_maybe_source_line(
+fn format_maybe_source_line(
source_line: Option<String>,
- line_number: Option<i64>,
start_column: Option<i64>,
end_column: Option<i64>,
is_error: bool,
level: usize,
) -> String {
- if source_line.is_none() || line_number.is_none() {
+ if source_line.is_none() || start_column.is_none() || end_column.is_none() {
return "".to_string();
}
- let source_line = source_line.as_ref().unwrap();
+ let source_line = source_line.unwrap();
// sometimes source_line gets set with an empty string, which then outputs
// an empty source line when displayed, so need just short circuit here.
// Also short-circuit on error line too long.
@@ -76,12 +62,6 @@ pub fn format_maybe_source_line(
assert!(start_column.is_some());
assert!(end_column.is_some());
- let line_number = line_number.unwrap().to_string();
- let line_color = colors::black_on_white(line_number.to_string());
- let line_number_len = line_number.len();
- let line_padding =
- colors::black_on_white(format!("{:indent$}", "", indent = line_number_len))
- .to_string();
let mut s = String::new();
let start_column = start_column.unwrap();
let end_column = end_column.unwrap();
@@ -107,16 +87,7 @@ pub fn format_maybe_source_line(
let indent = format!("{:indent$}", "", indent = level);
- format!(
- "\n\n{}{} {}\n{}{} {}\n",
- indent, line_color, source_line, indent, line_padding, color_underline
- )
-}
-
-/// Format a message to preface with `error: ` with ansi codes for red.
-pub fn format_error_message(msg: String) -> String {
- let preamble = colors::red("error:".to_string());
- format!("{} {}", preamble, msg)
+ format!("\n{}{}\n{}{}", indent, source_line, indent, color_underline)
}
/// Wrapper around deno_core::JSError which provides color to_string.
@@ -141,63 +112,44 @@ impl Deref for JSError {
}
}
-impl DisplayFormatter for JSError {
- fn format_category_and_code(&self) -> String {
- "".to_string()
- }
-
- fn format_message(&self, _level: usize) -> String {
- format!(
- "{}{}",
- colors::red_bold("error: ".to_string()),
- self.0.message.clone()
- )
- }
-
- fn format_related_info(&self) -> String {
- "".to_string()
- }
-
- fn format_source_line(&self, level: usize) -> String {
- format_maybe_source_line(
- self.0.source_line.clone(),
- self.0.line_number,
- self.0.start_column,
- self.0.end_column,
- true,
- level,
- )
- }
-
- fn format_source_name(&self) -> String {
- let e = &self.0;
- if e.script_resource_name.is_none() {
- return "".to_string();
- }
-
- format!(
- "\n► {}",
- format_maybe_source_name(
- e.script_resource_name.clone(),
- e.line_number,
- e.start_column.map(|n| n + 1),
- )
- )
- }
-}
-
impl fmt::Display for JSError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // When the stack frame array is empty, but the source location given by
+ // (script_resource_name, line_number, start_column + 1) exists, this is
+ // likely a syntax error. For the sake of formatting we treat it like it was
+ // given as a single stack frame.
+ let formatted_frames = if self.0.formatted_frames.is_empty()
+ && self.0.script_resource_name.is_some()
+ && self.0.line_number.is_some()
+ && self.0.start_column.is_some()
+ {
+ vec![format!(
+ "{}:{}:{}",
+ colors::cyan(self.0.script_resource_name.clone().unwrap()),
+ colors::yellow(self.0.line_number.unwrap().to_string()),
+ colors::yellow((self.0.start_column.unwrap() + 1).to_string())
+ )]
+ } else {
+ self.0.formatted_frames.clone()
+ };
+
write!(
f,
- "{}{}{}",
- self.format_message(0),
- self.format_source_name(),
- self.format_source_line(0),
+ "{}",
+ &format_stack(
+ true,
+ format!(
+ "{}: {}",
+ colors::red_bold("error".to_string()),
+ self.0.message.clone()
+ ),
+ self.0.source_line.clone(),
+ self.0.start_column,
+ self.0.end_column,
+ &formatted_frames,
+ 0
+ )
)?;
- for formatted_frame in &self.0.formatted_frames {
- write!(f, "\n at {}", formatted_frame)?;
- }
Ok(())
}
}
@@ -210,24 +162,8 @@ mod tests {
use crate::colors::strip_ansi_codes;
#[test]
- fn test_format_none_source_name() {
- let actual = format_maybe_source_name(None, None, None);
- assert_eq!(actual, "");
- }
-
- #[test]
- fn test_format_some_source_name() {
- let actual = format_maybe_source_name(
- Some("file://foo/bar.ts".to_string()),
- Some(1),
- Some(2),
- );
- assert_eq!(strip_ansi_codes(&actual), "file://foo/bar.ts:1:2");
- }
-
- #[test]
fn test_format_none_source_line() {
- let actual = format_maybe_source_line(None, None, None, None, false, 0);
+ let actual = format_maybe_source_line(None, None, None, false, 0);
assert_eq!(actual, "");
}
@@ -236,20 +172,13 @@ mod tests {
let actual = format_maybe_source_line(
Some("console.log('foo');".to_string()),
Some(8),
- Some(8),
Some(11),
true,
0,
);
assert_eq!(
strip_ansi_codes(&actual),
- "\n\n8 console.log(\'foo\');\n ~~~\n"
+ "\nconsole.log(\'foo\');\n ~~~"
);
}
-
- #[test]
- fn test_format_error_message() {
- let actual = format_error_message("foo".to_string());
- assert_eq!(strip_ansi_codes(&actual), "error: foo");
- }
}
diff --git a/cli/tests/038_checkjs.js.out b/cli/tests/038_checkjs.js.out
index deaf77211..92b8e2fd0 100644
--- a/cli/tests/038_checkjs.js.out
+++ b/cli/tests/038_checkjs.js.out
@@ -1,15 +1,21 @@
-[WILDCARD]
-error TS2552: Cannot find name 'consol'. Did you mean 'console'?
+[WILDCARD]error TS2552: Cannot find name 'consol'. Did you mean 'console'?
+consol.log("hello world!");
+~~~~~~
+ at [WILDCARD]tests/038_checkjs.js:2:1
-[WILDCARD]tests/038_checkjs.js:2:1
+ 'console' is declared here.
+ declare var console: Console;
+ ~~~~~~~
+ at [WILDCARD]
-2 consol.log("hello world!");
-[WILDCARD]
error TS2552: Cannot find name 'Foo'. Did you mean 'foo'?
+const foo = new Foo();
+ ~~~
+ at [WILDCARD]tests/038_checkjs.js:6:17
-[WILDCARD]tests/038_checkjs.js:6:17
+ 'foo' is declared here.
+ const foo = new Foo();
+ ~~~
+ at [WILDCARD]tests/038_checkjs.js:6:7
-6 const foo = new Foo();
-[WILDCARD]
Found 2 errors.
-[WILDCARD] \ No newline at end of file
diff --git a/cli/tests/044_bad_resource.ts.out b/cli/tests/044_bad_resource.ts.out
index a54c800f8..609851477 100644
--- a/cli/tests/044_bad_resource.ts.out
+++ b/cli/tests/044_bad_resource.ts.out
@@ -1,6 +1,4 @@
-[WILDCARD]
-error: Uncaught BadResource: Bad resource ID
-[WILDCARD]dispatch_json.ts:[WILDCARD]
+[WILDCARD]error: Uncaught BadResource: Bad resource ID
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at Object.sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async main ([WILDCARD]tests/044_bad_resource.ts:[WILDCARD])
diff --git a/cli/tests/async_error.ts.out b/cli/tests/async_error.ts.out
index 6e22799c2..7e32cd3dd 100644
--- a/cli/tests/async_error.ts.out
+++ b/cli/tests/async_error.ts.out
@@ -2,10 +2,7 @@
before error
world
error: Uncaught Error: error
-[WILDCARD]tests/async_error.ts:5:9
-
-5 throw Error("error");
- ^
-
+ throw Error("error");
+ ^
at foo ([WILDCARD]tests/async_error.ts:5:9)
at [WILDCARD]tests/async_error.ts:8:1
diff --git a/cli/tests/config.ts.out b/cli/tests/config.ts.out
index db5a8340e..b08761ac1 100644
--- a/cli/tests/config.ts.out
+++ b/cli/tests/config.ts.out
@@ -1,10 +1,7 @@
[WILDCARD]Unsupported compiler options in "[WILDCARD]config.tsconfig.json"
The following options were ignored:
module, target
-[WILDCARD]error TS2532: Object is possibly 'undefined'.
-
-[WILDCARD]tests/config.ts:3:5
-
-3 if (map.get("bar").foo) {
- ~~~~~~~~~~~~~~
-
+error TS2532: Object is possibly 'undefined'.
+if (map.get("bar").foo) {
+ ~~~~~~~~~~~~~~
+ at [WILDCARD]tests/config.ts:3:5
diff --git a/cli/tests/error_001.ts.out b/cli/tests/error_001.ts.out
index 3c7e2828e..d4103349a 100644
--- a/cli/tests/error_001.ts.out
+++ b/cli/tests/error_001.ts.out
@@ -1,9 +1,6 @@
[WILDCARD]error: Uncaught Error: bad
-[WILDCARD]tests/error_001.ts:2:9
-
-2 throw Error("bad");
- ^
-
+ throw Error("bad");
+ ^
at foo ([WILDCARD]tests/error_001.ts:2:9)
at bar ([WILDCARD]tests/error_001.ts:6:3)
at [WILDCARD]tests/error_001.ts:9:1
diff --git a/cli/tests/error_002.ts.out b/cli/tests/error_002.ts.out
index 292544a33..2aae770f8 100644
--- a/cli/tests/error_002.ts.out
+++ b/cli/tests/error_002.ts.out
@@ -1,9 +1,6 @@
[WILDCARD]error: Uncaught Error: exception from mod1
-[WILDCARD]tests/subdir/mod1.ts:16:9
-
-16 throw Error("exception from mod1");
- ^
-
+ throw Error("exception from mod1");
+ ^
at throwsError ([WILDCARD]tests/subdir/mod1.ts:16:9)
at foo ([WILDCARD]tests/error_002.ts:4:3)
at [WILDCARD]tests/error_002.ts:7:1
diff --git a/cli/tests/error_003_typescript.ts.out b/cli/tests/error_003_typescript.ts.out
index b5854c20f..ba113d12c 100644
--- a/cli/tests/error_003_typescript.ts.out
+++ b/cli/tests/error_003_typescript.ts.out
@@ -1,9 +1,6 @@
[WILDCARD]error TS2322: Type '{ a: { b: { c(): { d: number; }; }; }; }' is not assignable to type '{ a: { b: { c(): { d: string; }; }; }; }'.
The types of 'a.b.c().d' are incompatible between these types.
Type 'number' is not assignable to type 'string'.
-
-[WILDCARD]/cli/tests/error_003_typescript.ts:20:1
-
-20 x = y;
- ^
-
+x = y;
+^
+ at [WILDCARD]/tests/error_003_typescript.ts:20:1
diff --git a/cli/tests/error_004_missing_module.ts.out b/cli/tests/error_004_missing_module.ts.out
index e82cb00da..87db14026 100644
--- a/cli/tests/error_004_missing_module.ts.out
+++ b/cli/tests/error_004_missing_module.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/bad-module.ts" from "[WILDCARD]/error_004_missing_module.ts"
-[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at Object.sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
diff --git a/cli/tests/error_005_missing_dynamic_import.ts.out b/cli/tests/error_005_missing_dynamic_import.ts.out
index a67241ec1..0ec1dcb97 100644
--- a/cli/tests/error_005_missing_dynamic_import.ts.out
+++ b/cli/tests/error_005_missing_dynamic_import.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/bad-module.ts" from "[WILDCARD]/error_005_missing_dynamic_import.ts"
-[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at Object.sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
diff --git a/cli/tests/error_006_import_ext_failure.ts.out b/cli/tests/error_006_import_ext_failure.ts.out
index 57830c405..2cac6c76a 100644
--- a/cli/tests/error_006_import_ext_failure.ts.out
+++ b/cli/tests/error_006_import_ext_failure.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/non-existent" from "[WILDCARD]/error_006_import_ext_failure.ts"
-[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at Object.sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
diff --git a/cli/tests/error_008_checkjs.js.out b/cli/tests/error_008_checkjs.js.out
index 5c50e8513..2d93ffd01 100644
--- a/cli/tests/error_008_checkjs.js.out
+++ b/cli/tests/error_008_checkjs.js.out
@@ -1,7 +1,4 @@
[WILDCARD]error: Uncaught ReferenceError: consol is not defined
-[WILDCARD]tests/error_008_checkjs.js:2:1
-
-2 consol.log("hello world!");
- ^
-
+consol.log("hello world!");
+^
at [WILDCARD]tests/error_008_checkjs.js:2:1
diff --git a/cli/tests/error_011_bad_module_specifier.ts.out b/cli/tests/error_011_bad_module_specifier.ts.out
index d85177dc1..23421b135 100644
--- a/cli/tests/error_011_bad_module_specifier.ts.out
+++ b/cli/tests/error_011_bad_module_specifier.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught URIError: relative import path "bad-module.ts" not prefixed with / or ./ or ../ Imported from "[WILDCARD]/error_011_bad_module_specifier.ts"
-[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at Object.sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at resolveModules ([WILDCARD]compiler/imports.ts:[WILDCARD])
diff --git a/cli/tests/error_012_bad_dynamic_import_specifier.ts.out b/cli/tests/error_012_bad_dynamic_import_specifier.ts.out
index 59b968e81..57ca909ca 100644
--- a/cli/tests/error_012_bad_dynamic_import_specifier.ts.out
+++ b/cli/tests/error_012_bad_dynamic_import_specifier.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught URIError: relative import path "bad-module.ts" not prefixed with / or ./ or ../ Imported from "[WILDCARD]/error_012_bad_dynamic_import_specifier.ts"
-[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at Object.sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at resolveModules ([WILDCARD]compiler/imports.ts:[WILDCARD])
diff --git a/cli/tests/error_017_hide_long_source_ts.ts.out b/cli/tests/error_017_hide_long_source_ts.ts.out
index 4b4016b84..6606c8523 100644
--- a/cli/tests/error_017_hide_long_source_ts.ts.out
+++ b/cli/tests/error_017_hide_long_source_ts.ts.out
@@ -1,3 +1,2 @@
[WILDCARD]error TS2532: Object is possibly 'undefined'.
-
-► file:///[WILDCARD]cli/tests/error_017_hide_long_source_ts.ts:2:1
+ at [WILDCARD]tests/error_017_hide_long_source_ts.ts:2:1
diff --git a/cli/tests/error_018_hide_long_source_js.js.out b/cli/tests/error_018_hide_long_source_js.js.out
index dbdd924df..37265d659 100644
--- a/cli/tests/error_018_hide_long_source_js.js.out
+++ b/cli/tests/error_018_hide_long_source_js.js.out
@@ -1,3 +1,2 @@
error: Uncaught TypeError: Cannot read property 'a' of undefined
-► file:///[WILDCARD]cli/tests/error_018_hide_long_source_js.js:2:206
at file:///[WILDCARD]cli/tests/error_018_hide_long_source_js.js:2:206
diff --git a/cli/tests/error_syntax.js.out b/cli/tests/error_syntax.js.out
index 6253f3dd5..202e04a32 100644
--- a/cli/tests/error_syntax.js.out
+++ b/cli/tests/error_syntax.js.out
@@ -1,6 +1,4 @@
error: Uncaught SyntaxError: Unexpected identifier
-[WILDCARD]tests/error_syntax.js:3:6
-
-3 (the following is a syntax error ^^ ! )
- ~~~~~~~~~
-
+(the following is a syntax error ^^ ! )
+ ~~~~~~~~~
+ at [WILDCARD]tests/error_syntax.js:3:6
diff --git a/cli/tests/error_syntax_empty_trailing_line.mjs.out b/cli/tests/error_syntax_empty_trailing_line.mjs.out
index 1f1c96cd3..6e8a268e9 100644
--- a/cli/tests/error_syntax_empty_trailing_line.mjs.out
+++ b/cli/tests/error_syntax_empty_trailing_line.mjs.out
@@ -1,2 +1,2 @@
error: Uncaught SyntaxError: Unexpected end of input
-► file:///[WILDCARD]cli/tests/error_syntax_empty_trailing_line.mjs:[WILDCARD]
+ at [WILDCARD]tests/error_syntax_empty_trailing_line.mjs:[WILDCARD]
diff --git a/cli/tests/error_type_definitions.ts.out b/cli/tests/error_type_definitions.ts.out
index 55d0e4dad..7fcbb9592 100644
--- a/cli/tests/error_type_definitions.ts.out
+++ b/cli/tests/error_type_definitions.ts.out
@@ -1,5 +1,4 @@
[WILDCARD]error: Uncaught URIError: relative import path "baz" not prefixed with / or ./ or ../ Imported from "[WILDCARD]/type_definitions/bar.d.ts"
-[WILDCARD]ops/dispatch_json.ts:[WILDCARD]
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at Object.sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at Object.resolveModules ([WILDCARD]ops/compiler.ts:[WILDCARD])
diff --git a/core/js_errors.rs b/core/js_errors.rs
index 8429d731b..0e3f8cb91 100644
--- a/core/js_errors.rs
+++ b/core/js_errors.rs
@@ -1,11 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-// TODO: This currently only applies to uncaught exceptions. It would be nice to
-// also have source maps for situations like this:
-// const err = new Error("Boo!");
-// console.log(err.stack);
-// It would require calling into Rust from Error.prototype.prepareStackTrace.
-
use crate::ErrBox;
use rusty_v8 as v8;
use std::convert::TryFrom;
@@ -260,7 +254,6 @@ fn format_source_loc(
line_number: i64,
column_number: i64,
) -> String {
- // TODO match this style with how typescript displays errors.
let line_number = line_number;
let column_number = column_number;
format!("{}:{}:{}", file_name, line_number, column_number)