diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/02_error.js | 104 | ||||
-rw-r--r-- | core/bindings.rs | 1 | ||||
-rw-r--r-- | core/error.rs | 22 | ||||
-rw-r--r-- | core/ops_builtin.rs | 7 |
4 files changed, 81 insertions, 53 deletions
diff --git a/core/02_error.js b/core/02_error.js index c6b808169..a7d5d0ee2 100644 --- a/core/02_error.js +++ b/core/02_error.js @@ -71,7 +71,7 @@ } // Keep in sync with `cli/fmt_errors.rs`. - function formatLocation(callSite, formatFileNameFn) { + function formatLocation(callSite) { if (callSite.isNative()) { return "native"; } @@ -81,7 +81,7 @@ const fileName = callSite.getFileName(); if (fileName) { - result += formatFileNameFn(fileName); + result += core.opSync("op_format_file_name", fileName); } else { if (callSite.isEval()) { const evalOrigin = callSite.getEvalOrigin(); @@ -107,7 +107,7 @@ } // Keep in sync with `cli/fmt_errors.rs`. - function formatCallSite(callSite, formatFileNameFn) { + function formatCallSite(callSite) { let result = ""; const functionName = callSite.getFunctionName(); @@ -160,11 +160,11 @@ } else if (functionName) { result += functionName; } else { - result += formatLocation(callSite, formatFileNameFn); + result += formatLocation(callSite); return result; } - result += ` (${formatLocation(callSite, formatFileNameFn)})`; + result += ` (${formatLocation(callSite)})`; return result; } @@ -189,57 +189,55 @@ }; } - /** Returns a function that can be used as `Error.prepareStackTrace`. */ - function createPrepareStackTrace(formatFileNameFn) { - return function prepareStackTrace( - error, - callSites, - ) { - const mappedCallSites = ArrayPrototypeMap(callSites, (callSite) => { - const fileName = callSite.getFileName(); - const lineNumber = callSite.getLineNumber(); - const columnNumber = callSite.getColumnNumber(); - if (fileName && lineNumber != null && columnNumber != null) { - return patchCallSite( - callSite, - core.applySourceMap({ - fileName, - lineNumber, - columnNumber, - }), - ); - } - return callSite; - }); - ObjectDefineProperties(error, { - __callSiteEvals: { value: [], configurable: true }, - }); - const formattedCallSites = []; - for (const callSite of mappedCallSites) { - ArrayPrototypePush(error.__callSiteEvals, evaluateCallSite(callSite)); - ArrayPrototypePush( - formattedCallSites, - formatCallSite(callSite, formatFileNameFn), + /** A function that can be used as `Error.prepareStackTrace`. */ + function prepareStackTrace( + error, + callSites, + ) { + const mappedCallSites = ArrayPrototypeMap(callSites, (callSite) => { + const fileName = callSite.getFileName(); + const lineNumber = callSite.getLineNumber(); + const columnNumber = callSite.getColumnNumber(); + if (fileName && lineNumber != null && columnNumber != null) { + return patchCallSite( + callSite, + core.applySourceMap({ + fileName, + lineNumber, + columnNumber, + }), ); } - const message = error.message !== undefined ? error.message : ""; - const name = error.name !== undefined ? error.name : "Error"; - let messageLine; - if (name != "" && message != "") { - messageLine = `${name}: ${message}`; - } else if ((name || message) != "") { - messageLine = name || message; - } else { - messageLine = ""; - } - return messageLine + - ArrayPrototypeJoin( - ArrayPrototypeMap(formattedCallSites, (s) => `\n at ${s}`), - "", - ); - }; + return callSite; + }); + ObjectDefineProperties(error, { + __callSiteEvals: { value: [], configurable: true }, + }); + const formattedCallSites = []; + for (const callSite of mappedCallSites) { + ArrayPrototypePush(error.__callSiteEvals, evaluateCallSite(callSite)); + ArrayPrototypePush( + formattedCallSites, + formatCallSite(callSite), + ); + } + const message = error.message !== undefined ? error.message : ""; + const name = error.name !== undefined ? error.name : "Error"; + let messageLine; + if (name != "" && message != "") { + messageLine = `${name}: ${message}`; + } else if ((name || message) != "") { + messageLine = name || message; + } else { + messageLine = ""; + } + return messageLine + + ArrayPrototypeJoin( + ArrayPrototypeMap(formattedCallSites, (s) => `\n at ${s}`), + "", + ); } - ObjectAssign(globalThis.__bootstrap.core, { createPrepareStackTrace }); + ObjectAssign(globalThis.__bootstrap.core, { prepareStackTrace }); ObjectFreeze(globalThis.__bootstrap.core); })(this); diff --git a/core/bindings.rs b/core/bindings.rs index 889229bb5..1816cdefb 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -243,6 +243,7 @@ pub fn initialize_context<'s>( set_func(scope, core_val, "destructureError", destructure_error); set_func(scope, core_val, "terminate", terminate); set_func(scope, core_val, "applySourceMap", apply_source_map); + // Direct bindings on `window`. set_func(scope, global, "queueMicrotask", queue_microtask); diff --git a/core/error.rs b/core/error.rs index 8e6c43482..045dd5a15 100644 --- a/core/error.rs +++ b/core/error.rs @@ -2,6 +2,7 @@ use crate::runtime::JsRuntime; use crate::source_map::apply_source_map; +use crate::url::Url; use anyhow::Error; use std::borrow::Cow; use std::collections::HashMap; @@ -431,6 +432,27 @@ pub(crate) fn is_instance_of_error<'s>( false } +const DATA_URL_ABBREV_THRESHOLD: usize = 150; + +pub fn format_file_name(file_name: &str) -> String { + abbrev_file_name(file_name).unwrap_or_else(|| file_name.to_string()) +} + +fn abbrev_file_name(file_name: &str) -> Option<String> { + if file_name.len() <= DATA_URL_ABBREV_THRESHOLD { + return None; + } + let url = Url::parse(file_name).ok()?; + if url.scheme() != "data" { + return None; + } + let (head, tail) = url.path().split_once(',')?; + let len = tail.len(); + let start = tail.get(0..20)?; + let end = tail.get(len - 20..)?; + Some(format!("{}:{},{}......{}", url.scheme(), head, start, end)) +} + #[cfg(test)] mod tests { use super::*; diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 4b566e916..23837bbb7 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -1,3 +1,4 @@ +use crate::error::format_file_name; use crate::error::type_error; use crate::include_js_files; use crate::ops_metrics::OpMetrics; @@ -34,6 +35,7 @@ pub(crate) fn init_builtins() -> Extension { op_write::decl(), op_shutdown::decl(), op_metrics::decl(), + op_format_file_name::decl(), ]) .build() } @@ -183,3 +185,8 @@ async fn op_shutdown( let resource = state.borrow().resource_table.get_any(rid)?; resource.shutdown().await } + +#[op] +fn op_format_file_name(file_name: String) -> Result<String, Error> { + Ok(format_file_name(&file_name)) +} |