1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 15:49:44 -05:00

feat(ext/web): add globalThis.reportError() (#13799)

This commit is contained in:
Nayeem Rahman 2022-04-19 09:59:51 +01:00 committed by GitHub
parent a64e63c361
commit c30d95f2e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 93 additions and 17 deletions

View file

@ -48,8 +48,9 @@ pub fn format_location(frame: &JsStackFrame) -> String {
return cyan("native").to_string();
}
let mut result = String::new();
if let Some(file_name) = &frame.file_name {
result += &cyan(&format_file_name(file_name)).to_string();
let file_name = frame.file_name.clone().unwrap_or_default();
if !file_name.is_empty() {
result += &cyan(&format_file_name(&file_name)).to_string();
} else {
if frame.is_eval {
result +=

View file

@ -2753,3 +2753,14 @@ fn deno_no_prompt_environment_variable() {
.unwrap();
assert!(output.status.success());
}
itest!(report_error {
args: "run --quiet report_error.ts",
output: "report_error.ts.out",
exit_code: 1,
});
itest!(report_error_handled {
args: "run --quiet report_error_handled.ts",
output: "report_error_handled.ts.out",
});

3
cli/tests/testdata/report_error.ts vendored Normal file
View file

@ -0,0 +1,3 @@
console.log(1);
reportError(new Error("foo"));
console.log(2);

View file

@ -0,0 +1,5 @@
1
error: Uncaught Error: foo
reportError(new Error("foo"));
^
at [WILDCARD]/report_error.ts:2:13

View file

@ -0,0 +1,19 @@
addEventListener("error", (event) => {
console.log({
cancelable: event.cancelable,
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error,
});
event.preventDefault();
});
onerror = (event) => {
console.log("onerror() called", event.error);
};
console.log(1);
reportError(new Error("foo"));
console.log(2);

View file

@ -0,0 +1,13 @@
1
{
cancelable: true,
message: "Uncaught Error: foo",
filename: "[WILDCARD]/report_error_handled.ts",
lineno: 18,
colno: 13,
error: Error: foo
at [WILDCARD]/report_error_handled.ts:18:13
}
onerror() called Error: foo
at [WILDCARD]/report_error_handled.ts:18:13
2

View file

@ -1367,6 +1367,20 @@
reportExceptionStackedCalls--;
}
function checkThis(thisArg) {
if (thisArg !== null && thisArg !== undefined && thisArg !== globalThis) {
throw new TypeError("Illegal invocation");
}
}
// https://html.spec.whatwg.org/#dom-reporterror
function reportError(error) {
checkThis(this);
const prefix = "Failed to call 'reportError'";
webidl.requiredArguments(arguments.length, 1, { prefix });
reportException(error);
}
window.Event = Event;
window.EventTarget = EventTarget;
window.ErrorEvent = ErrorEvent;
@ -1377,6 +1391,7 @@
window.dispatchEvent = EventTarget.prototype.dispatchEvent;
window.addEventListener = EventTarget.prototype.addEventListener;
window.removeEventListener = EventTarget.prototype.removeEventListener;
window.reportError = reportError;
window.__bootstrap.eventTarget = {
EventTarget,
setEventTargetData,

View file

@ -890,3 +890,22 @@ declare class DecompressionStream {
readonly readable: ReadableStream<Uint8Array>;
readonly writable: WritableStream<Uint8Array>;
}
/** Dispatch an uncaught exception. Similar to a synchronous version of:
* ```ts
* setTimeout(() => { throw error; }, 0);
* ```
* The error can not be caught with a `try/catch` block. An error event will
* be dispatched to the global scope. You can prevent the error from being
* reported to the console with `Event.prototype.preventDefault()`:
* ```ts
* addEventListener("error", (event) => {
* event.preventDefault();
* });
* reportError(new Error("foo")); // Will not be reported.
* ```
* In Deno, this error will terminate the process if not intercepted like above.
*/
declare function reportError(
error: any,
): void;

View file

@ -638,7 +638,8 @@ impl WebWorker {
v8::Local::<v8::Value>::new(scope, poll_for_messages_fn);
let fn_ = v8::Local::<v8::Function>::try_from(poll_for_messages).unwrap();
let undefined = v8::undefined(scope);
fn_.call(scope, undefined.into(), &[]).unwrap();
// This call may return `None` if worker is terminated.
fn_.call(scope, undefined.into(), &[]);
}
}

View file

@ -3646,18 +3646,8 @@
"queue-microtask.any.worker.html": true
},
"scripting": {
"reporterror.any.html": [
"self.reportError(1)",
"self.reportError(TypeError)",
"self.reportError(undefined)",
"self.reportError() doesn't invoke getters"
],
"reporterror.any.worker.html": [
"self.reportError(1)",
"self.reportError(TypeError)",
"self.reportError(undefined)",
"self.reportError() doesn't invoke getters"
]
"reporterror.any.html": false,
"reporterror.any.worker.html": false
},
"structured-clone": {
"structured-clone.any.html": [
@ -4237,7 +4227,6 @@
"opening-handshake": {
"003-sets-origin.worker.html": false
},
"Create-on-worker-shutdown.any.worker.html": false,
"Send-data.worker.html": true,
"Send-data.worker.html?wpt_flags=h2": false,
"Send-data.worker.html?wss": true,
@ -4648,4 +4637,4 @@
"idlharness.https.any.worker.html": true,
"idlharness-shadowrealm.window.html": false
}
}
}