napi-rs/napi/src/js_values/error.rs

89 lines
3.1 KiB
Rust

use std::ffi::CString;
use std::ptr;
use crate::{check_status, sys, Env, Error};
pub struct JsError(Error);
pub struct JsTypeError(Error);
pub struct JsRangeError(Error);
macro_rules! impl_object_methods {
($js_value:ident, $kind:expr) => {
impl $js_value {
#[inline(always)]
/// # Safety
///
/// This function is safety if env is not null ptr.
pub unsafe fn into_value(self, env: sys::napi_env) -> sys::napi_value {
let error_status = format!("{:?}", self.0.status);
let status_len = error_status.len();
let error_code_string = CString::new(error_status).unwrap();
let reason_len = self.0.reason.len();
let reason = CString::new(self.0.reason).unwrap();
let mut error_code = ptr::null_mut();
let mut reason_string = ptr::null_mut();
let mut js_error = ptr::null_mut();
let create_code_status = sys::napi_create_string_utf8(
env,
error_code_string.as_ptr(),
status_len,
&mut error_code,
);
debug_assert!(create_code_status == sys::Status::napi_ok);
let create_reason_status =
sys::napi_create_string_utf8(env, reason.as_ptr(), reason_len, &mut reason_string);
debug_assert!(create_reason_status == sys::Status::napi_ok);
let create_error_status = $kind(env, error_code, reason_string, &mut js_error);
debug_assert!(create_error_status == sys::Status::napi_ok);
js_error
}
#[inline(always)]
/// # Safety
///
/// This function is safety if env is not null ptr.
pub unsafe fn throw_into(self, env: sys::napi_env) {
let js_error = self.into_value(env);
let throw_status = sys::napi_throw(env, js_error);
debug_assert!(throw_status == sys::Status::napi_ok);
}
#[inline(always)]
pub fn throw(&self, env: &Env) -> Result<(), Error> {
let error_status = format!("{:?}", self.0.status);
let status_len = error_status.len();
let error_code_string = CString::new(error_status).unwrap();
let reason_len = self.0.reason.len();
let reason = CString::new(self.0.reason.clone()).unwrap();
let mut error_code = ptr::null_mut();
let mut reason_string = ptr::null_mut();
let mut js_error = ptr::null_mut();
check_status!(unsafe {
sys::napi_create_string_utf8(
env.0,
error_code_string.as_ptr(),
status_len,
&mut error_code,
)
})?;
check_status!(unsafe {
sys::napi_create_string_utf8(env.0, reason.as_ptr(), reason_len, &mut reason_string)
})?;
check_status!(unsafe { $kind(env.0, error_code, reason_string, &mut js_error) })?;
check_status!(unsafe { sys::napi_throw(env.0, js_error) })
}
}
impl From<Error> for $js_value {
fn from(err: Error) -> Self {
Self(err)
}
}
};
}
impl_object_methods!(JsError, sys::napi_create_error);
impl_object_methods!(JsTypeError, sys::napi_create_type_error);
impl_object_methods!(JsRangeError, sys::napi_create_range_error);