1
0
Fork 0
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:
Aaron O'Mullan 2021-04-22 02:50:50 +02:00 committed by GitHub
parent 89bb774010
commit ff9ff4a377
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 18 additions and 30 deletions

View file

@ -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();

View file

@ -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.

View file

@ -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();

View file

@ -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;
} }

View file

@ -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();

View file

@ -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`);

View file

@ -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');

View file

@ -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();

View file

@ -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");
},
); );
} }