mini_v8/
error.rs

1use crate::*;
2use std::error::Error as StdError;
3use std::fmt;
4use std::result::Result as StdResult;
5
6/// `std::result::Result` specialized for this crate's `Error` type.
7pub type Result<T> = StdResult<T, Error>;
8
9/// An error originating from `MiniV8` usage.
10#[derive(Debug)]
11pub enum Error {
12    /// A Rust value could not be converted to a JavaScript value.
13    ToJsConversionError {
14        /// Name of the Rust type that could not be converted.
15        from: &'static str,
16        /// Name of the JavaScript type that could not be created.
17        to: &'static str,
18    },
19    /// A JavaScript value could not be converted to the expected Rust type.
20    FromJsConversionError {
21        /// Name of the JavaScript type that could not be converted.
22        from: &'static str,
23        /// Name of the Rust type that could not be created.
24        to: &'static str,
25    },
26    /// An evaluation timeout occurred.
27    Timeout,
28    /// A mutable callback has triggered JavaScript code that has called the same mutable callback
29    /// again.
30    ///
31    /// This is an error because a mutable callback can only be borrowed mutably once.
32    RecursiveMutCallback,
33    /// An evaluation timeout was specified from within a Rust function embedded in V8.
34    InvalidTimeout,
35    /// A custom error that occurs during runtime.
36    ///
37    /// This can be used for returning user-defined errors from callbacks.
38    ExternalError(Box<dyn StdError + 'static>),
39    /// An exception that occurred within the JavaScript environment.
40    Value(Value),
41}
42
43impl Error {
44    /// Normalizes an error into a JavaScript value.
45    pub fn to_value(self, mv8: &MiniV8) -> Value {
46        match self {
47            Error::Value(value) => value,
48            Error::ToJsConversionError { .. } |
49            Error::FromJsConversionError { .. } => {
50                let object = mv8.create_object();
51                let _ = object.set("name", "TypeError");
52                let _ = object.set("message", self.to_string());
53                Value::Object(object)
54            },
55            _ => {
56                let object = mv8.create_object();
57                let _ = object.set("name", "Error");
58                let _ = object.set("message", self.to_string());
59                Value::Object(object)
60            },
61        }
62    }
63
64    pub(crate) fn from_js_conversion(from: &'static str, to: &'static str) -> Error {
65        Error::FromJsConversionError { from, to }
66    }
67}
68
69impl StdError for Error {
70    fn description(&self) -> &'static str {
71        "JavaScript execution error"
72    }
73}
74
75impl fmt::Display for Error {
76    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
77        match self {
78            Error::ToJsConversionError { from, to } => {
79                write!(fmt, "error converting {} to JavaScript {}", from, to)
80            },
81            Error::FromJsConversionError { from, to } => {
82                write!(fmt, "error converting JavaScript {} to {}", from, to)
83            },
84            Error::Timeout => write!(fmt, "evaluation timed out"),
85            Error::RecursiveMutCallback => write!(fmt, "mutable callback called recursively"),
86            Error::InvalidTimeout => write!(fmt, "invalid request for evaluation timeout"),
87            Error::ExternalError(ref err) => err.fmt(fmt),
88            Error::Value(v) => write!(fmt, "JavaScript runtime error ({})", v.type_name()),
89        }
90    }
91}