mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
refactor(core): simplify error handling (#10297)
- register builtin v8 errors in core.js so consumers don't have to - remove complexity of error args handling (consumers must provide a constructor with custom args, core simply provides msg arg)
This commit is contained in:
parent
89bb774010
commit
ff9ff4a377
9 changed files with 18 additions and 30 deletions
|
@ -20,7 +20,6 @@ pub fn create_js_runtime(setup: impl FnOnce(&mut JsRuntime)) -> JsRuntime {
|
||||||
"init",
|
"init",
|
||||||
r#"
|
r#"
|
||||||
Deno.core.ops();
|
Deno.core.ops();
|
||||||
Deno.core.registerErrorClass('Error', Error);
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -799,7 +799,6 @@ delete Object.prototype.__proto__;
|
||||||
|
|
||||||
// Setup the compiler runtime during the build process.
|
// Setup the compiler runtime during the build process.
|
||||||
core.ops();
|
core.ops();
|
||||||
core.registerErrorClass("Error", Error);
|
|
||||||
|
|
||||||
// A build time only op that provides some setup information that is used to
|
// A build time only op that provides some setup information that is used to
|
||||||
// ensure the snapshot is setup properly.
|
// ensure the snapshot is setup properly.
|
||||||
|
|
|
@ -27,7 +27,6 @@ fn create_js_runtime() -> JsRuntime {
|
||||||
"init",
|
"init",
|
||||||
r#"
|
r#"
|
||||||
Deno.core.ops();
|
Deno.core.ops();
|
||||||
Deno.core.registerErrorClass('Error', Error);
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
26
core/core.js
26
core/core.js
|
@ -6,7 +6,15 @@
|
||||||
const { send } = window.Deno.core;
|
const { send } = window.Deno.core;
|
||||||
|
|
||||||
let opsCache = {};
|
let opsCache = {};
|
||||||
const errorMap = {};
|
const errorMap = {
|
||||||
|
// Builtin v8 / JS errors
|
||||||
|
Error,
|
||||||
|
RangeError,
|
||||||
|
ReferenceError,
|
||||||
|
SyntaxError,
|
||||||
|
TypeError,
|
||||||
|
URIError,
|
||||||
|
};
|
||||||
let nextPromiseId = 1;
|
let nextPromiseId = 1;
|
||||||
const promiseMap = new Map();
|
const promiseMap = new Map();
|
||||||
const RING_SIZE = 4 * 1024;
|
const RING_SIZE = 4 * 1024;
|
||||||
|
@ -71,28 +79,24 @@
|
||||||
return send(opsCache[opName], promiseId, control, zeroCopy);
|
return send(opsCache[opName], promiseId, control, zeroCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerErrorClass(errorName, className, args) {
|
function registerErrorClass(className, errorClass) {
|
||||||
if (typeof errorMap[errorName] !== "undefined") {
|
if (typeof errorMap[className] !== "undefined") {
|
||||||
throw new TypeError(`Error class for "${errorName}" already registered`);
|
throw new TypeError(`Error class for "${className}" already registered`);
|
||||||
}
|
}
|
||||||
errorMap[errorName] = [className, args ?? []];
|
errorMap[className] = errorClass;
|
||||||
}
|
|
||||||
|
|
||||||
function getErrorClassAndArgs(errorName) {
|
|
||||||
return errorMap[errorName] ?? [undefined, []];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwrapOpResult(res) {
|
function unwrapOpResult(res) {
|
||||||
// .$err_class_name is a special key that should only exist on errors
|
// .$err_class_name is a special key that should only exist on errors
|
||||||
if (res?.$err_class_name) {
|
if (res?.$err_class_name) {
|
||||||
const className = res.$err_class_name;
|
const className = res.$err_class_name;
|
||||||
const [ErrorClass, args] = getErrorClassAndArgs(className);
|
const ErrorClass = errorMap[className];
|
||||||
if (!ErrorClass) {
|
if (!ErrorClass) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unregistered error class: "${className}"\n ${res.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`,
|
`Unregistered error class: "${className}"\n ${res.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw new ErrorClass(res.message, ...args);
|
throw new ErrorClass(res.message);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,6 @@ const _newline = new Uint8Array([10]);
|
||||||
function print(value) {
|
function print(value) {
|
||||||
Deno.core.dispatchByName('op_print', 0, value.toString(), _newline);
|
Deno.core.dispatchByName('op_print', 0, value.toString(), _newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally we register the error class used by op_sum
|
|
||||||
// so that it throws the correct class.
|
|
||||||
Deno.core.registerErrorClass('Error', Error);
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -55,7 +55,6 @@ async function serve(rid) {
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
Deno.core.ops();
|
Deno.core.ops();
|
||||||
Deno.core.registerErrorClass("Error", Error);
|
|
||||||
|
|
||||||
const listenerRid = listen();
|
const listenerRid = listen();
|
||||||
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4544/\n`);
|
Deno.core.print(`http_bench_ops listening on http://127.0.0.1:4544/\n`);
|
||||||
|
|
|
@ -122,8 +122,6 @@ mod tests {
|
||||||
r#"
|
r#"
|
||||||
// First we initialize the ops cache. This maps op names to their id's.
|
// First we initialize the ops cache. This maps op names to their id's.
|
||||||
Deno.core.ops();
|
Deno.core.ops();
|
||||||
// Register the error class.
|
|
||||||
Deno.core.registerErrorClass('Error', Error);
|
|
||||||
|
|
||||||
async function f1() {
|
async function f1() {
|
||||||
await Deno.core.opAsync('op_throw', 'hello');
|
await Deno.core.opAsync('op_throw', 'hello');
|
||||||
|
|
|
@ -28,7 +28,6 @@ fn create_js_runtime() -> JsRuntime {
|
||||||
"init",
|
"init",
|
||||||
r#"
|
r#"
|
||||||
Deno.core.ops();
|
Deno.core.ops();
|
||||||
Deno.core.registerErrorClass('Error', Error);
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -186,16 +186,11 @@ delete Object.prototype.__proto__;
|
||||||
core.registerErrorClass("Http", errors.Http);
|
core.registerErrorClass("Http", errors.Http);
|
||||||
core.registerErrorClass("Busy", errors.Busy);
|
core.registerErrorClass("Busy", errors.Busy);
|
||||||
core.registerErrorClass("NotSupported", errors.NotSupported);
|
core.registerErrorClass("NotSupported", errors.NotSupported);
|
||||||
core.registerErrorClass("Error", Error);
|
|
||||||
core.registerErrorClass("RangeError", RangeError);
|
|
||||||
core.registerErrorClass("ReferenceError", ReferenceError);
|
|
||||||
core.registerErrorClass("SyntaxError", SyntaxError);
|
|
||||||
core.registerErrorClass("TypeError", TypeError);
|
|
||||||
core.registerErrorClass("URIError", URIError);
|
|
||||||
core.registerErrorClass(
|
core.registerErrorClass(
|
||||||
"DOMExceptionOperationError",
|
"DOMExceptionOperationError",
|
||||||
DOMException,
|
function DOMExceptionOperationError(msg) {
|
||||||
"OperationError",
|
DOMException.prototype.constructor.call(this, msg, "OperationError");
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue