Skip to content

Commit

Permalink
refactor: rework error handling (#878)
Browse files Browse the repository at this point in the history
Closes #810
  • Loading branch information
crowlKats authored Jan 8, 2025
1 parent 2741f28 commit 22939ed
Show file tree
Hide file tree
Showing 89 changed files with 1,571 additions and 2,049 deletions.
74 changes: 62 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde_v8 = { version = "0.237.0", path = "./serde_v8" }

deno_ast = { version = "=0.40.0", features = ["transpiling"] }
deno_core_icudata = "0.74.0"
deno_error = { version = "0.5.3", features = ["serde_json", "serde", "url", "tokio"] }
deno_unsync = "0.4.1"
v8 = { version = "130.0.6", default-features = false }

Expand Down Expand Up @@ -61,7 +62,7 @@ static_assertions = "1"
strum = { version = "0.25.0", features = ["derive"] }
strum_macros = "0.25.0"
testing_macros = "0.2.11"
thiserror = "1"
thiserror = "2"
tokio = { version = "1", features = ["full"] }
twox-hash = { version = "2.0.0", default-features = false, features = ["xxhash64"] }
url = { version = "2", features = ["serde", "expose_internals"] }
Expand Down
31 changes: 25 additions & 6 deletions core/00_infra.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
PromisePrototypeThen,
RangeError,
ReferenceError,
SafeArrayIterator,
SafeMap,
StringPrototypeSplit,
SymbolFor,
Expand Down Expand Up @@ -85,7 +86,7 @@
registerErrorClass("TypeError", TypeError);
registerErrorClass("URIError", URIError);

function buildCustomError(className, message, code) {
function buildCustomError(className, message, additionalProperties) {
let error;
try {
error = errorMap[className]?.(message);
Expand All @@ -97,8 +98,16 @@
// Strip buildCustomError() calls from stack trace
if (typeof error == "object") {
ErrorCaptureStackTrace(error, buildCustomError);
if (code) {
error.code = code;
if (additionalProperties) {
for (const property of new SafeArrayIterator(additionalProperties)) {
const key = property[0];
if (!(key in error)) {
ObjectDefineProperty(error, key, {
value: property[1],
writable: false,
});
}
}
}
}
return error;
Expand Down Expand Up @@ -180,9 +189,19 @@
const err = errorBuilder ? errorBuilder(res.message) : new Error(
`Unregistered error class: "${className}"\n ${res.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`,
);
// Set .code if error was a known OS error, see error_codes.rs
if (res.code) {
err.code = res.code;

if (res.additional_properties) {
for (
const property of new SafeArrayIterator(res.additional_properties)
) {
const key = property[0];
if (!(key in err)) {
ObjectDefineProperty(err, key, {
value: property[1],
writable: false,
});
}
}
}
// Strip eventLoopTick() calls from stack trace
ErrorCaptureStackTrace(err, eventLoopTick);
Expand Down
4 changes: 3 additions & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ bytes.workspace = true
capacity_builder = "0.1.0"
cooked-waker.workspace = true
deno_core_icudata = { workspace = true, optional = true }
deno_error.workspace = true
deno_ops.workspace = true
deno_unsync.workspace = true
futures.workspace = true
Expand All @@ -47,10 +48,11 @@ serde_v8.workspace = true
smallvec.workspace = true
sourcemap.workspace = true
static_assertions.workspace = true
thiserror.workspace = true
tokio.workspace = true
url.workspace = true
v8.workspace = true
wasm_dep_analyzer = "0.1.0"
wasm_dep_analyzer = "0.2.0"

[dev-dependencies]
bencher.workspace = true
Expand Down
39 changes: 34 additions & 5 deletions core/async_cancel.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2018-2025 the Deno authors. MIT license.

use std::any::type_name;
use std::any::Any;
use std::borrow::Cow;
use std::error::Error;
use std::fmt;
Expand All @@ -10,16 +11,16 @@ use std::io;
use std::pin::Pin;
use std::rc::Rc;

use crate::RcLike;
use crate::Resource;
use deno_error::JsErrorClass;
use futures::future::FusedFuture;
use futures::future::Future;
use futures::future::TryFuture;
use futures::task::Context;
use futures::task::Poll;
use pin_project::pin_project;

use crate::RcLike;
use crate::Resource;

use self::internal as i;

#[derive(Debug, Default)]
Expand Down Expand Up @@ -242,6 +243,35 @@ impl From<Canceled> for io::Error {
}
}

impl From<Canceled> for deno_error::JsErrorBox {
fn from(value: Canceled) -> Self {
deno_error::JsErrorBox::from_err(value)
}
}

impl JsErrorClass for Canceled {
fn get_class(&self) -> Cow<'static, str> {
let io_err: io::Error = self.to_owned().into();
io_err.get_class()
}

fn get_message(&self) -> Cow<'static, str> {
let io_err: io::Error = self.to_owned().into();
io_err.get_message()
}

fn get_additional_properties(
&self,
) -> Vec<(Cow<'static, str>, Cow<'static, str>)> {
let io_err: io::Error = self.to_owned().into();
io_err.get_additional_properties()
}

fn as_any(&self) -> &dyn Any {
self
}
}

mod internal {
use super::Abortable;
use super::CancelHandle;
Expand Down Expand Up @@ -666,7 +696,6 @@ mod internal {
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Error;
use futures::future::pending;
use futures::future::poll_fn;
use futures::future::ready;
Expand Down Expand Up @@ -782,7 +811,7 @@ mod tests {
// Cancel a spawned task before it actually runs.
let cancel_handle = Rc::new(CancelHandle::new());
let future = spawn(async { panic!("the task should not be spawned") })
.map_err(Error::from)
.map_err(anyhow::Error::from)
.try_or_cancel(&cancel_handle);
cancel_handle.cancel();
let error = future.await.unwrap_err();
Expand Down
4 changes: 2 additions & 2 deletions core/benches/ops/async.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright 2018-2025 the Deno authors. MIT license.

use bencher::*;
use deno_core::error::generic_error;
use deno_core::*;
use deno_error::JsErrorBox;
use std::ffi::c_void;
use tokio::runtime::Runtime;

Expand Down Expand Up @@ -119,7 +119,7 @@ fn bench_op(
..Default::default()
});
let err_mapper =
|err| generic_error(format!("{op} test failed ({call}): {err:?}"));
|err| JsErrorBox::generic(format!("{op} test failed ({call}): {err:?}"));

let args = (0..arg_count)
.map(|n| format!("arg{n}"))
Expand Down
8 changes: 5 additions & 3 deletions core/benches/ops/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#![allow(deprecated)]
use bencher::*;
use deno_core::error::generic_error;
use deno_core::*;
use std::borrow::Cow;
use std::ffi::c_void;
Expand Down Expand Up @@ -184,8 +183,11 @@ fn bench_op(
})),
..Default::default()
});
let err_mapper =
|err| generic_error(format!("{op} test failed ({call}): {err:?}"));
let err_mapper = |err| {
deno_error::JsErrorBox::generic(format!(
"{op} test failed ({call}): {err:?}"
))
};

let args = (0..arg_count)
.map(|n| format!("arg{n}"))
Expand Down
Loading

0 comments on commit 22939ed

Please sign in to comment.