Skip to content

Commit 73f3512

Browse files
committed
Allow catching of exception
1 parent 39210dd commit 73f3512

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

src/err.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{error, fmt};
22

3-
use rquickjs::Error as JSError;
3+
use rquickjs::{Ctx, Error as JSError, Exception, Value};
44
use serde::{de, ser};
55

66
/// This type represents all possible errors that can occur when serializing or
@@ -11,6 +11,10 @@ impl Error {
1111
pub(crate) fn new(msg: impl Into<ErrorImpl>) -> Self {
1212
Error(Box::new(msg.into()))
1313
}
14+
15+
pub fn catch<'js>(self, ctx: &Ctx<'js>) -> CaughtError<'js> {
16+
self.0.catch(ctx)
17+
}
1418
}
1519

1620
/// Alias for a `Result` with the error type `rquickjs_serde::Error`.
@@ -54,6 +58,26 @@ pub enum ErrorImpl {
5458
Rquickjs(JSError),
5559
}
5660

61+
impl ErrorImpl {
62+
pub fn catch<'js>(self, ctx: &Ctx<'js>) -> CaughtError<'js> {
63+
match self {
64+
ErrorImpl::Message(msg) => CaughtError::Message(msg),
65+
ErrorImpl::Rquickjs(JSError::Exception) => {
66+
let value = ctx.catch();
67+
if let Some(ex) = value
68+
.as_object()
69+
.and_then(|x| Exception::from_object(x.clone()))
70+
{
71+
CaughtError::Exception(ex)
72+
} else {
73+
CaughtError::Value(value)
74+
}
75+
}
76+
ErrorImpl::Rquickjs(e) => CaughtError::Error(e),
77+
}
78+
}
79+
}
80+
5781
impl fmt::Display for ErrorImpl {
5882
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5983
match self {
@@ -74,3 +98,31 @@ impl From<JSError> for ErrorImpl {
7498
ErrorImpl::Rquickjs(value)
7599
}
76100
}
101+
102+
/// An error type containing possible thrown exception values.
103+
#[derive(Debug)]
104+
pub enum CaughtError<'js> {
105+
/// Error was an exception and an instance of Error
106+
Exception(Exception<'js>),
107+
/// Error was an exception but not an instance of Error.
108+
Value(Value<'js>),
109+
/// Error wasn't an exception
110+
Error(JSError),
111+
/// A generic error message
112+
Message(String),
113+
}
114+
115+
impl<'js> fmt::Display for CaughtError<'js> {
116+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117+
match self {
118+
CaughtError::Error(e) => e.fmt(f),
119+
CaughtError::Exception(e) => e.fmt(f),
120+
CaughtError::Value(e) => {
121+
writeln!(f, "Exception generated by quickjs: {e:?}")
122+
}
123+
CaughtError::Message(msg) => write!(f, "{msg}"),
124+
}
125+
}
126+
}
127+
128+
impl<'js> error::Error for CaughtError<'js> {}

0 commit comments

Comments
 (0)