mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
feat(ext/web): add globalThis.reportError() (#13799)
This commit is contained in:
parent
a64e63c361
commit
c30d95f2e3
10 changed files with 93 additions and 17 deletions
|
@ -48,8 +48,9 @@ pub fn format_location(frame: &JsStackFrame) -> String {
|
||||||
return cyan("native").to_string();
|
return cyan("native").to_string();
|
||||||
}
|
}
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
if let Some(file_name) = &frame.file_name {
|
let file_name = frame.file_name.clone().unwrap_or_default();
|
||||||
result += &cyan(&format_file_name(file_name)).to_string();
|
if !file_name.is_empty() {
|
||||||
|
result += &cyan(&format_file_name(&file_name)).to_string();
|
||||||
} else {
|
} else {
|
||||||
if frame.is_eval {
|
if frame.is_eval {
|
||||||
result +=
|
result +=
|
||||||
|
|
|
@ -2753,3 +2753,14 @@ fn deno_no_prompt_environment_variable() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(output.status.success());
|
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
3
cli/tests/testdata/report_error.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
console.log(1);
|
||||||
|
reportError(new Error("foo"));
|
||||||
|
console.log(2);
|
5
cli/tests/testdata/report_error.ts.out
vendored
Normal file
5
cli/tests/testdata/report_error.ts.out
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
1
|
||||||
|
error: Uncaught Error: foo
|
||||||
|
reportError(new Error("foo"));
|
||||||
|
^
|
||||||
|
at [WILDCARD]/report_error.ts:2:13
|
19
cli/tests/testdata/report_error_handled.ts
vendored
Normal file
19
cli/tests/testdata/report_error_handled.ts
vendored
Normal 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);
|
13
cli/tests/testdata/report_error_handled.ts.out
vendored
Normal file
13
cli/tests/testdata/report_error_handled.ts.out
vendored
Normal 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
|
|
@ -1367,6 +1367,20 @@
|
||||||
reportExceptionStackedCalls--;
|
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.Event = Event;
|
||||||
window.EventTarget = EventTarget;
|
window.EventTarget = EventTarget;
|
||||||
window.ErrorEvent = ErrorEvent;
|
window.ErrorEvent = ErrorEvent;
|
||||||
|
@ -1377,6 +1391,7 @@
|
||||||
window.dispatchEvent = EventTarget.prototype.dispatchEvent;
|
window.dispatchEvent = EventTarget.prototype.dispatchEvent;
|
||||||
window.addEventListener = EventTarget.prototype.addEventListener;
|
window.addEventListener = EventTarget.prototype.addEventListener;
|
||||||
window.removeEventListener = EventTarget.prototype.removeEventListener;
|
window.removeEventListener = EventTarget.prototype.removeEventListener;
|
||||||
|
window.reportError = reportError;
|
||||||
window.__bootstrap.eventTarget = {
|
window.__bootstrap.eventTarget = {
|
||||||
EventTarget,
|
EventTarget,
|
||||||
setEventTargetData,
|
setEventTargetData,
|
||||||
|
|
19
ext/web/lib.deno_web.d.ts
vendored
19
ext/web/lib.deno_web.d.ts
vendored
|
@ -890,3 +890,22 @@ declare class DecompressionStream {
|
||||||
readonly readable: ReadableStream<Uint8Array>;
|
readonly readable: ReadableStream<Uint8Array>;
|
||||||
readonly writable: WritableStream<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;
|
||||||
|
|
|
@ -638,7 +638,8 @@ impl WebWorker {
|
||||||
v8::Local::<v8::Value>::new(scope, poll_for_messages_fn);
|
v8::Local::<v8::Value>::new(scope, poll_for_messages_fn);
|
||||||
let fn_ = v8::Local::<v8::Function>::try_from(poll_for_messages).unwrap();
|
let fn_ = v8::Local::<v8::Function>::try_from(poll_for_messages).unwrap();
|
||||||
let undefined = v8::undefined(scope);
|
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(), &[]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3646,18 +3646,8 @@
|
||||||
"queue-microtask.any.worker.html": true
|
"queue-microtask.any.worker.html": true
|
||||||
},
|
},
|
||||||
"scripting": {
|
"scripting": {
|
||||||
"reporterror.any.html": [
|
"reporterror.any.html": false,
|
||||||
"self.reportError(1)",
|
"reporterror.any.worker.html": false
|
||||||
"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"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"structured-clone": {
|
"structured-clone": {
|
||||||
"structured-clone.any.html": [
|
"structured-clone.any.html": [
|
||||||
|
@ -4237,7 +4227,6 @@
|
||||||
"opening-handshake": {
|
"opening-handshake": {
|
||||||
"003-sets-origin.worker.html": false
|
"003-sets-origin.worker.html": false
|
||||||
},
|
},
|
||||||
"Create-on-worker-shutdown.any.worker.html": false,
|
|
||||||
"Send-data.worker.html": true,
|
"Send-data.worker.html": true,
|
||||||
"Send-data.worker.html?wpt_flags=h2": false,
|
"Send-data.worker.html?wpt_flags=h2": false,
|
||||||
"Send-data.worker.html?wss": true,
|
"Send-data.worker.html?wss": true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue