quickjs-oxide 0.4.0

A safe Rust JavaScript engine targeting semantic parity with QuickJS
Documentation
//! The API's error type.

use std::fmt;

use super::value::Value;
use crate::engine::api::error::Error;
use crate::engine::value::JsStringError;

/// Why an API call failed.
#[derive(Clone, Debug, PartialEq)]
pub enum RuntimeError {
    /// JavaScript threw this value.
    Exception(Value),
    /// An API call was made through a `Context` or `Runtime` from inside a
    /// host function or callback, which has its own scope.
    Reentered,
    /// The script was interrupted ([`InterruptHandle`](super::InterruptHandle)
    /// or [`Host::interrupt`](super::Host::interrupt)); no `catch` or
    /// `finally` of it ran.
    Interrupted,
    /// A host function panicked while the runtime ran it; the runtime's
    /// state is unknown and every later call fails.
    Poisoned,
    /// The engine does not have this (`"realms"`).
    Unsupported(&'static str),
    /// The front end rejected the source.
    Compile(Error),
    /// The heap cap was reached.
    OutOfMemory,
    /// The embedder broke one of the API's preconditions.
    Invariant(&'static str),
    /// The engine failed internally.
    Internal(String),
}

impl fmt::Display for RuntimeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            RuntimeError::Exception(_) => f.write_str("JavaScript exception"),
            RuntimeError::Reentered => {
                f.write_str("the runtime was re-entered from a host callback")
            }
            RuntimeError::Interrupted => f.write_str("interrupted"),
            RuntimeError::Poisoned => {
                f.write_str("the runtime is poisoned: a host function panicked")
            }
            RuntimeError::Unsupported(what) => write!(f, "{what} are not supported"),
            RuntimeError::Compile(error) => write!(f, "{error}"),
            RuntimeError::OutOfMemory => f.write_str("out of memory"),
            RuntimeError::Invariant(what) => write!(f, "invariant violated: {what}"),
            RuntimeError::Internal(message) => write!(f, "internal error: {message}"),
        }
    }
}

impl std::error::Error for RuntimeError {}

impl From<Error> for RuntimeError {
    fn from(error: Error) -> Self {
        RuntimeError::Compile(error)
    }
}

impl From<JsStringError> for RuntimeError {
    fn from(error: JsStringError) -> Self {
        match error {
            JsStringError::OutOfMemory => RuntimeError::OutOfMemory,
            other => RuntimeError::Internal(other.to_string()),
        }
    }
}

impl From<oxide_core::HeapError> for RuntimeError {
    fn from(error: oxide_core::HeapError) -> Self {
        match error {
            oxide_core::HeapError::OutOfMemory => RuntimeError::OutOfMemory,
            other => RuntimeError::Internal(format!("{other:?}")),
        }
    }
}