mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
chore(ext/web): use Error.captureStackTrace
in DOMException
constructor (#23986)
This makes `DOMException`'s `stack` property behave the same as native errors' – `stack` is now an own accessor property on every instance, and the getter calls `Error.prepareStackTrace`. Upgrades `deno_core` to 0.284.0. --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
parent
32f655db54
commit
29a075de2b
5 changed files with 33 additions and 57 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -1303,9 +1303,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_core"
|
name = "deno_core"
|
||||||
version = "0.283.0"
|
version = "0.284.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f5043f9f636a3fe021e63e41c946499e1706d7565126065c60912fe5c77e54e"
|
checksum = "f4a5c809e81be26fcfbbce4275573251f6a156137b67059889e9e38f73e75b63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -1753,9 +1753,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ops"
|
name = "deno_ops"
|
||||||
version = "0.159.0"
|
version = "0.160.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b26cc5277982de16514282447f8674f9048d4f1b2c0d55c088d0a7d3bf6db385"
|
checksum = "517e54d41a2da6a69b8f534294334d79d9115ddd43aea88a5ceefdb717e6d85e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-rules",
|
"proc-macro-rules",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -5754,9 +5754,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_v8"
|
name = "serde_v8"
|
||||||
version = "0.192.0"
|
version = "0.193.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7b616df6c4ff5643dd503cbfe119175ebebfd4132512e33de4971f1e91d5739"
|
checksum = "21ec612dfc7ab70330b5405e8015b25e637bbfe1d79c4bd173557933aea66e76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -44,7 +44,7 @@ repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
deno_ast = { version = "=0.38.2", features = ["transpiling"] }
|
deno_ast = { version = "=0.38.2", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.283.0" }
|
deno_core = { version = "0.284.0" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.148.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.148.0", path = "./bench_util" }
|
||||||
deno_lockfile = "0.20.0"
|
deno_lockfile = "0.20.0"
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
import { primordials } from "ext:core/mod.js";
|
import { primordials } from "ext:core/mod.js";
|
||||||
const {
|
const {
|
||||||
ArrayPrototypeSlice,
|
|
||||||
Error,
|
|
||||||
ErrorPrototype,
|
ErrorPrototype,
|
||||||
|
ErrorCaptureStackTrace,
|
||||||
ObjectDefineProperty,
|
ObjectDefineProperty,
|
||||||
ObjectCreate,
|
ObjectCreate,
|
||||||
ObjectEntries,
|
ObjectEntries,
|
||||||
|
ObjectHasOwn,
|
||||||
ObjectPrototypeIsPrototypeOf,
|
ObjectPrototypeIsPrototypeOf,
|
||||||
ObjectSetPrototypeOf,
|
ObjectSetPrototypeOf,
|
||||||
Symbol,
|
Symbol,
|
||||||
|
@ -27,7 +27,6 @@ import { createFilteredInspectProxy } from "ext:deno_console/01_console.js";
|
||||||
const _name = Symbol("name");
|
const _name = Symbol("name");
|
||||||
const _message = Symbol("message");
|
const _message = Symbol("message");
|
||||||
const _code = Symbol("code");
|
const _code = Symbol("code");
|
||||||
const _error = Symbol("error");
|
|
||||||
|
|
||||||
// Defined in WebIDL 4.3.
|
// Defined in WebIDL 4.3.
|
||||||
// https://webidl.spec.whatwg.org/#idl-DOMException
|
// https://webidl.spec.whatwg.org/#idl-DOMException
|
||||||
|
@ -113,8 +112,7 @@ class DOMException {
|
||||||
this[_code] = code;
|
this[_code] = code;
|
||||||
this[webidl.brand] = webidl.brand;
|
this[webidl.brand] = webidl.brand;
|
||||||
|
|
||||||
this[_error] = new Error(message);
|
ErrorCaptureStackTrace(this, DOMException);
|
||||||
this[_error].name = "DOMException";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get message() {
|
get message() {
|
||||||
|
@ -133,13 +131,16 @@ class DOMException {
|
||||||
}
|
}
|
||||||
|
|
||||||
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
|
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
|
||||||
if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) {
|
if (ObjectHasOwn(this, "stack")) {
|
||||||
return this[_error].stack;
|
const stack = this.stack;
|
||||||
} else {
|
if (typeof stack === "string") {
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
return inspect(
|
return inspect(
|
||||||
createFilteredInspectProxy({
|
createFilteredInspectProxy({
|
||||||
object: this,
|
object: this,
|
||||||
evaluate: false,
|
evaluate: ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this),
|
||||||
keys: [
|
keys: [
|
||||||
"message",
|
"message",
|
||||||
"name",
|
"name",
|
||||||
|
@ -150,32 +151,6 @@ class DOMException {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ObjectDefineProperty(DOMException.prototype, "stack", {
|
|
||||||
get() {
|
|
||||||
return this[_error].stack;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
this[_error].stack = value;
|
|
||||||
},
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// `DOMException` isn't a native error, so `Error.prepareStackTrace()` is
|
|
||||||
// not called when accessing `.stack`, meaning our structured stack trace
|
|
||||||
// hack doesn't apply. This patches it in.
|
|
||||||
ObjectDefineProperty(DOMException.prototype, "__callSiteEvals", {
|
|
||||||
get() {
|
|
||||||
// Call the stack getter so `__callSiteEvals` get populated.
|
|
||||||
this[_error].stack;
|
|
||||||
// To be extra sure, use an empty array if `__callSiteEvals` is still not there,
|
|
||||||
// eg. if the user overrides `Error.prepareStackTrace`.
|
|
||||||
const callSiteEvals = this[_error].__callSiteEvals ?? [];
|
|
||||||
return ArrayPrototypeSlice(callSiteEvals, 1);
|
|
||||||
},
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype);
|
ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
thrown: DOMException: foo
|
thrown: Error: foo
|
||||||
at new DOMException (ext:deno_web/01_dom_exception.js:[WILDCARD])
|
|
||||||
at [WILDCARD]
|
at [WILDCARD]
|
||||||
at Object.evalContext (ext:core/01_core.js:[WILDCARD])
|
at Object.evalContext (ext:core/01_core.js:[WILDCARD])
|
||||||
at file:///[WILDCARD]/eval_context_throw_dom_exception.js:1:48,
|
at file:///[WILDCARD]/eval_context_throw_dom_exception.js:1:48,
|
||||||
|
|
|
@ -23,8 +23,10 @@ Deno.test(function nameToCodeMappingPrototypeAccess() {
|
||||||
Reflect.deleteProperty(objectPrototype, "pollution");
|
Reflect.deleteProperty(objectPrototype, "pollution");
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test(function callSitesEvalsDoesntThrow() {
|
Deno.test(function hasStackAccessor() {
|
||||||
const e2 = new DOMException("asdf");
|
const e2 = new DOMException("asdf");
|
||||||
// @ts-ignore no types for `__callSiteEvals` but it's observable.
|
const desc = Object.getOwnPropertyDescriptor(e2, "stack");
|
||||||
assert(Array.isArray(e2.__callSiteEvals));
|
assert(desc);
|
||||||
|
assert(typeof desc.get === "function");
|
||||||
|
assert(typeof desc.set === "function");
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue