summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2021-09-18 14:40:04 +0100
committerGitHub <noreply@github.com>2021-09-18 15:40:04 +0200
commit75ca013f076f443dce3d38f31a168295351ed0e5 (patch)
treea8f369429ff650516a513a0416e8984f457835a4
parentf840906943849f5a09981e172d57e84301b77386 (diff)
fix(cli/fmt_errors): Abbreviate long data URLs in stack traces (#12127)
Co-authored-by: Mike White <mike.white@auctane.com>
-rw-r--r--cli/fmt_errors.rs31
-rw-r--r--cli/ops/errors.rs10
-rw-r--r--cli/tests/integration/run_tests.rs6
-rw-r--r--cli/tests/testdata/import_data_url_error_stack.ts.out2
-rw-r--r--cli/tests/testdata/long_data_url_formatting.ts3
-rw-r--r--cli/tests/testdata/long_data_url_formatting.ts.out8
-rw-r--r--core/02_error.js17
-rw-r--r--runtime/js/40_error_stack.js7
-rw-r--r--runtime/js/99_main.js18
9 files changed, 80 insertions, 22 deletions
diff --git a/cli/fmt_errors.rs b/cli/fmt_errors.rs
index 53a8535f0..2b95f0fc7 100644
--- a/cli/fmt_errors.rs
+++ b/cli/fmt_errors.rs
@@ -5,13 +5,40 @@ use crate::colors::italic_bold;
use crate::colors::red;
use crate::colors::yellow;
use deno_core::error::{AnyError, JsError, JsStackFrame};
+use deno_core::url::Url;
use std::error::Error;
use std::fmt;
use std::ops::Deref;
const SOURCE_ABBREV_THRESHOLD: usize = 150;
+const DATA_URL_ABBREV_THRESHOLD: usize = 150;
-// Keep in sync with `runtime/js/40_error_stack.js`.
+pub fn format_file_name(file_name: &str) -> String {
+ if file_name.len() > DATA_URL_ABBREV_THRESHOLD {
+ if let Ok(url) = Url::parse(file_name) {
+ if url.scheme() == "data" {
+ let data_path = url.path();
+ if let Some(data_pieces) = data_path.split_once(',') {
+ let data_length = data_pieces.1.len();
+ if let Some(data_start) = data_pieces.1.get(0..20) {
+ if let Some(data_end) = data_pieces.1.get(data_length - 20..) {
+ return format!(
+ "{}:{},{}......{}",
+ url.scheme(),
+ data_pieces.0,
+ data_start,
+ data_end
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ file_name.to_string()
+}
+
+// Keep in sync with `/core/error.js`.
pub fn format_location(frame: &JsStackFrame) -> String {
let _internal = frame
.file_name
@@ -22,7 +49,7 @@ pub fn format_location(frame: &JsStackFrame) -> String {
}
let mut result = String::new();
if let Some(file_name) = &frame.file_name {
- result += &cyan(&file_name).to_string();
+ result += &cyan(&format_file_name(file_name)).to_string();
} else {
if frame.is_eval {
result +=
diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs
index 453a9ff6b..a889b1b0d 100644
--- a/cli/ops/errors.rs
+++ b/cli/ops/errors.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use crate::diagnostics::Diagnostics;
+use crate::fmt_errors::format_file_name;
use crate::program_state::ProgramState;
use crate::source_maps::get_orig_position;
use crate::source_maps::CachedMaps;
@@ -16,6 +17,7 @@ use std::sync::Arc;
pub fn init(rt: &mut deno_core::JsRuntime) {
super::reg_sync(rt, "op_apply_source_map", op_apply_source_map);
super::reg_sync(rt, "op_format_diagnostic", op_format_diagnostic);
+ super::reg_sync(rt, "op_format_file_name", op_format_file_name);
}
#[derive(Deserialize)]
@@ -60,3 +62,11 @@ fn op_format_diagnostic(
let diagnostic: Diagnostics = serde_json::from_value(args)?;
Ok(json!(diagnostic.to_string()))
}
+
+fn op_format_file_name(
+ _state: &mut OpState,
+ file_name: String,
+ _: (),
+) -> Result<String, AnyError> {
+ Ok(format_file_name(&file_name))
+}
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 14e0e1241..04ba10b7b 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -1885,3 +1885,9 @@ itest!(dom_exception_formatting {
output: "dom_exception_formatting.ts.out",
exit_code: 1,
});
+
+itest!(long_data_url_formatting {
+ args: "run long_data_url_formatting.ts",
+ output: "long_data_url_formatting.ts.out",
+ exit_code: 1,
+});
diff --git a/cli/tests/testdata/import_data_url_error_stack.ts.out b/cli/tests/testdata/import_data_url_error_stack.ts.out
index d456ad0ea..ccd72e4ad 100644
--- a/cli/tests/testdata/import_data_url_error_stack.ts.out
+++ b/cli/tests/testdata/import_data_url_error_stack.ts.out
@@ -1,6 +1,6 @@
[WILDCARD]error: Uncaught Error: Hello 2
throw new Error(`Hello ${A.C}`);
^
- at a (data:application/typescript;base64,ZW51bSBBIHsKICBBLAogIEIsCiAgQywKIH0KIAogZXhwb3J0IGZ1bmN0aW9uIGEoKSB7CiAgIHRocm93IG5ldyBFcnJvcihgSGVsbG8gJHtBLkN9YCk7CiB9CiA=:8:10)
+ at a (data:application/typescript;base64,ZW51bSBBIHsKICBBLAog......JHtBLkN9YCk7CiB9CiA=:8:10)
at file:///[WILDCARD]/import_data_url_error_stack.ts:3:1
[WILDCARD]
diff --git a/cli/tests/testdata/long_data_url_formatting.ts b/cli/tests/testdata/long_data_url_formatting.ts
new file mode 100644
index 000000000..2ed2d5a03
--- /dev/null
+++ b/cli/tests/testdata/long_data_url_formatting.ts
@@ -0,0 +1,3 @@
+await import(
+ 'data:application/typescript,console.trace("foo"); const error = new Error("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); console.log(error.stack); throw error;'
+);
diff --git a/cli/tests/testdata/long_data_url_formatting.ts.out b/cli/tests/testdata/long_data_url_formatting.ts.out
new file mode 100644
index 000000000..ea78c2591
--- /dev/null
+++ b/cli/tests/testdata/long_data_url_formatting.ts.out
@@ -0,0 +1,8 @@
+[WILDCARD]Trace: foo
+ at data:application/typescript,console.trace("foo")......stack); throw error;:1:9
+Error: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ at data:application/typescript,console.trace("foo")......stack); throw error;:1:37
+error: Uncaught (in promise) Error: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+console.trace("foo"); const error = new Error("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); console.log(error.stack); throw error;
+ ^
+ at data:application/typescript,console.trace("foo")......stack); throw error;:1:37
diff --git a/core/02_error.js b/core/02_error.js
index c6f642630..4ec9f7267 100644
--- a/core/02_error.js
+++ b/core/02_error.js
@@ -70,7 +70,7 @@
}
// Keep in sync with `cli/fmt_errors.rs`.
- function formatLocation(callSite) {
+ function formatLocation(callSite, formatFileNameFn) {
if (callSite.isNative()) {
return "native";
}
@@ -80,7 +80,7 @@
const fileName = callSite.getFileName();
if (fileName) {
- result += fileName;
+ result += formatFileNameFn(fileName);
} else {
if (callSite.isEval()) {
const evalOrigin = callSite.getEvalOrigin();
@@ -106,7 +106,7 @@
}
// Keep in sync with `cli/fmt_errors.rs`.
- function formatCallSite(callSite) {
+ function formatCallSite(callSite, formatFileNameFn) {
let result = "";
const functionName = callSite.getFunctionName();
@@ -159,11 +159,11 @@
} else if (functionName) {
result += functionName;
} else {
- result += formatLocation(callSite);
+ result += formatLocation(callSite, formatFileNameFn);
return result;
}
- result += ` (${formatLocation(callSite)})`;
+ result += ` (${formatLocation(callSite, formatFileNameFn)})`;
return result;
}
@@ -205,7 +205,7 @@
* columnNumber: number
* }} sourceMappingFn
*/
- function createPrepareStackTrace(sourceMappingFn) {
+ function createPrepareStackTrace(sourceMappingFn, formatFileNameFn) {
return function prepareStackTrace(
error,
callSites,
@@ -235,7 +235,10 @@
const formattedCallSites = [];
for (const callSite of mappedCallSites) {
ArrayPrototypePush(error.__callSiteEvals, evaluateCallSite(callSite));
- ArrayPrototypePush(formattedCallSites, formatCallSite(callSite));
+ ArrayPrototypePush(
+ formattedCallSites,
+ formatCallSite(callSite, formatFileNameFn),
+ );
}
const message = error.message !== undefined ? error.message : "";
const name = error.name !== undefined ? error.name : "Error";
diff --git a/runtime/js/40_error_stack.js b/runtime/js/40_error_stack.js
index e73975044..c8f2aff5a 100644
--- a/runtime/js/40_error_stack.js
+++ b/runtime/js/40_error_stack.js
@@ -8,6 +8,10 @@
return core.opSync("op_format_diagnostic", diagnostics);
}
+ function opFormatFileName(location) {
+ return core.opSync("op_format_file_name", location);
+ }
+
function opApplySourceMap(location) {
const res = core.opSync("op_apply_source_map", location);
return {
@@ -18,7 +22,8 @@
}
window.__bootstrap.errorStack = {
- opApplySourceMap,
opFormatDiagnostics,
+ opFormatFileName,
+ opApplySourceMap,
};
})(this);
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index 5c1c04766..b16fabe8a 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -218,17 +218,13 @@ delete Object.prototype.__proto__;
);
build.setBuildInfo(runtimeOptions.target);
util.setLogDebug(runtimeOptions.debugFlag, source);
- // TODO(bartlomieju): a very crude way to disable
- // source mapping of errors. This condition is true
- // only for compiled standalone binaries.
- let prepareStackTrace;
- if (runtimeOptions.applySourceMaps) {
- prepareStackTrace = core.createPrepareStackTrace(
- errorStack.opApplySourceMap,
- );
- } else {
- prepareStackTrace = core.createPrepareStackTrace();
- }
+ const prepareStackTrace = core.createPrepareStackTrace(
+ // TODO(bartlomieju): a very crude way to disable
+ // source mapping of errors. This condition is true
+ // only for compiled standalone binaries.
+ runtimeOptions.applySourceMaps ? errorStack.opApplySourceMap : undefined,
+ errorStack.opFormatFileName,
+ );
// deno-lint-ignore prefer-primordials
Error.prepareStackTrace = prepareStackTrace;
}