Skip to content

Commit

Permalink
fix(core/js_error): Get frame data from prepareStackTrace() (#4690)
Browse files Browse the repository at this point in the history
Fixes: #2703
Fixes: #2710
Closes: #4153
Closes: #4232

Co-authored-by: Kevin (Kun) Kassimo Qian <[email protected]>
  • Loading branch information
nayeemrmn and kevinkassimo authored Apr 10, 2020
1 parent 195ad4c commit 8b45083
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 48 deletions.
18 changes: 17 additions & 1 deletion cli/fmt_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,21 @@ fn format_stack_frame(frame: &JSStackFrame, is_internal_frame: bool) -> String {
source_loc = colors::gray(source_loc).to_string();
}
if !frame.function_name.is_empty() {
format!("{} {} {}", at_prefix, function_name, source_loc)
if frame.is_async {
format!(
"{} {} {} {}",
at_prefix,
colors::gray("async".to_owned()).to_string(),
function_name,
source_loc
)
} else {
format!("{} {} {}", at_prefix, function_name, source_loc)
}
} else if frame.is_eval {
format!("{} eval {}", at_prefix, source_loc)
} else if frame.is_async {
format!("{} async {}", at_prefix, source_loc)
} else {
format!("{} {}", at_prefix, source_loc)
}
Expand Down Expand Up @@ -272,6 +284,7 @@ mod tests {
function_name: "foo".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 5,
Expand All @@ -280,6 +293,7 @@ mod tests {
function_name: "qat".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 1,
Expand All @@ -288,8 +302,10 @@ mod tests {
function_name: "".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
],
already_source_mapped: true,
};
let formatted_error = JSError(core_js_error).to_string();
let actual = strip_ansi_codes(&formatted_error);
Expand Down
60 changes: 55 additions & 5 deletions cli/js/error_stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ function callSiteToString(callSite: CallSite): string {
result += "async ";
}
if (isPromiseAll) {
result += `Promise.all (index ${callSite.getPromiseIndex})`;
result += `Promise.all (index ${callSite.getPromiseIndex()})`;
return result;
}
if (isMethodCall) {
Expand All @@ -163,11 +163,52 @@ function callSiteToString(callSite: CallSite): string {
return result;
}

interface CallSiteEval {
this: unknown;
typeName: string;
function: Function;
functionName: string;
methodName: string;
fileName: string;
lineNumber: number | null;
columnNumber: number | null;
evalOrigin: string | null;
isToplevel: boolean;
isEval: boolean;
isNative: boolean;
isConstructor: boolean;
isAsync: boolean;
isPromiseAll: boolean;
promiseIndex: number | null;
}

function evaluateCallSite(callSite: CallSite): CallSiteEval {
return {
this: callSite.getThis(),
typeName: callSite.getTypeName(),
function: callSite.getFunction(),
functionName: callSite.getFunctionName(),
methodName: callSite.getMethodName(),
fileName: callSite.getFileName(),
lineNumber: callSite.getLineNumber(),
columnNumber: callSite.getColumnNumber(),
evalOrigin: callSite.getEvalOrigin(),
isToplevel: callSite.isToplevel(),
isEval: callSite.isEval(),
isNative: callSite.isNative(),
isConstructor: callSite.isConstructor(),
isAsync: callSite.isAsync(),
isPromiseAll: callSite.isPromiseAll(),
promiseIndex: callSite.getPromiseIndex(),
};
}

function prepareStackTrace(
error: Error,
structuredStackTrace: CallSite[]
): string {
return (
Object.defineProperty(error, "__callSiteEvals", { value: [] });
const errorString =
`${error.name}: ${error.message}\n` +
structuredStackTrace
.map(
Expand All @@ -188,9 +229,18 @@ function prepareStackTrace(
return callSite;
}
)
.map((callSite): string => ` at ${callSiteToString(callSite)}`)
.join("\n")
);
.map((callSite): string => {
const callSiteEv = Object.freeze(evaluateCallSite(callSite));
if (callSiteEv.lineNumber != null && callSiteEv.columnNumber != null) {
// @ts-ignore
error["__callSiteEvals"].push(callSiteEv);
}
return ` at ${callSiteToString(callSite)}`;
})
.join("\n");
// @ts-ignore
Object.freeze(error["__callSiteEvals"]);
return errorString;
}

// @internal
Expand Down
28 changes: 23 additions & 5 deletions cli/source_maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,16 @@ pub fn apply_source_map<G: SourceMapGetter>(
) -> deno_core::JSError {
let mut mappings_map: CachedMaps = HashMap::new();

let mut frames = Vec::<JSStackFrame>::new();
for frame in &js_error.frames {
let f = frame_apply_source_map(&frame, &mut mappings_map, getter);
frames.push(f);
}
let frames = if !js_error.already_source_mapped {
let mut frames = Vec::<JSStackFrame>::new();
for frame in &js_error.frames {
let f = frame_apply_source_map(&frame, &mut mappings_map, getter);
frames.push(f);
}
frames
} else {
js_error.frames.clone()
};

let (script_resource_name, line_number, start_column) =
get_maybe_orig_position(
Expand Down Expand Up @@ -98,6 +103,7 @@ pub fn apply_source_map<G: SourceMapGetter>(
start_column,
end_column,
frames,
already_source_mapped: js_error.already_source_mapped,
}
}

Expand All @@ -121,6 +127,7 @@ fn frame_apply_source_map<G: SourceMapGetter>(
column,
is_eval: frame.is_eval,
is_constructor: frame.is_constructor,
is_async: frame.is_async,
}
}

Expand Down Expand Up @@ -255,6 +262,7 @@ mod tests {
function_name: "foo".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 5,
Expand All @@ -263,6 +271,7 @@ mod tests {
function_name: "qat".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 1,
Expand All @@ -271,8 +280,10 @@ mod tests {
function_name: "".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
],
already_source_mapped: false,
};
let getter = MockSourceMapGetter {};
let actual = apply_source_map(&core_js_error, &getter);
Expand All @@ -291,6 +302,7 @@ mod tests {
function_name: "foo".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 4,
Expand All @@ -299,6 +311,7 @@ mod tests {
function_name: "qat".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
JSStackFrame {
line_number: 1,
Expand All @@ -307,8 +320,10 @@ mod tests {
function_name: "".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
},
],
already_source_mapped: false,
};
assert_eq!(actual, expected);
}
Expand All @@ -329,7 +344,9 @@ mod tests {
function_name: "setLogDebug".to_string(),
is_eval: false,
is_constructor: false,
is_async: false,
}],
already_source_mapped: false,
};
let getter = MockSourceMapGetter {};
let actual = apply_source_map(&e, &getter);
Expand All @@ -348,6 +365,7 @@ mod tests {
start_column: Some(16),
end_column: None,
frames: vec![],
already_source_mapped: false,
};
let getter = MockSourceMapGetter {};
let actual = apply_source_map(&e, &getter);
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/044_bad_resource.ts.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[WILDCARD]
error: Uncaught BadResource: Bad resource ID
[WILDCARD]dispatch_json.ts:[WILDCARD]
at BadResource ([WILDCARD]errors.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async main ([WILDCARD]tests/044_bad_resource.ts:[WILDCARD])
8 changes: 6 additions & 2 deletions cli/tests/error_004_missing_module.ts.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/bad-module.ts" from "[WILDCARD]/error_004_missing_module.ts"
[WILDCARD]dispatch_json.ts:[WILDCARD]
at NotFound ([WILDCARD]errors.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync[WILDCARD] ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
8 changes: 6 additions & 2 deletions cli/tests/error_005_missing_dynamic_import.ts.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[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 NotFound ([WILDCARD]errors.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync[WILDCARD] ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
6 changes: 5 additions & 1 deletion cli/tests/error_006_import_ext_failure.ts.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/non-existent" from "[WILDCARD]/error_006_import_ext_failure.ts"
[WILDCARD]dispatch_json.ts:[WILDCARD]
at NotFound ([WILDCARD]errors.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]dispatch_json.ts:[WILDCARD])
at sendAsync[WILDCARD] ([WILDCARD]dispatch_json.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
13 changes: 8 additions & 5 deletions cli/tests/error_011_bad_module_specifier.ts.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[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 ($deno$/ops/dispatch_json.ts:[WILDCARD])
at sendSync ($deno$/ops/dispatch_json.ts:[WILDCARD])
at resolveModules ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at resolveModules ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
13 changes: 8 additions & 5 deletions cli/tests/error_012_bad_dynamic_import_specifier.ts.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[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 ($deno$/ops/dispatch_json.ts:[WILDCARD])
at sendSync ($deno$/ops/dispatch_json.ts:[WILDCARD])
at resolveModules ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at resolveModules ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
14 changes: 9 additions & 5 deletions cli/tests/error_type_definitions.ts.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[WILDCARD]error: Uncaught URIError: relative import path "baz" not prefixed with / or ./ or ../ Imported from "[WILDCARD]/type_definitions/bar.d.ts"
[WILDCARD]dispatch_json.ts:[WILDCARD]
at unwrapResponse ($deno$/ops/dispatch_json.ts:[WILDCARD])
at sendSync ($deno$/ops/dispatch_json.ts:[WILDCARD])
at resolveModules ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at processImports ($deno$/compiler/imports.ts:[WILDCARD])
at unwrapResponse ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at sendSync ([WILDCARD]ops/dispatch_json.ts:[WILDCARD])
at resolveModules ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async processImports ([WILDCARD]compiler/imports.ts:[WILDCARD])
at async compile ([WILDCARD]compiler.ts:[WILDCARD])
at async tsCompilerOnMessage ([WILDCARD]compiler.ts:[WILDCARD])
at async workerMessageRecvCallback ([WILDCARD]runtime_worker.ts:[WILDCARD])
Loading

0 comments on commit 8b45083

Please sign in to comment.