neon/sys/
error.rs

1use std::{mem::MaybeUninit, panic::Location, ptr};
2
3use super::{
4    bindings as napi,
5    raw::{Env, Local},
6};
7
8pub unsafe fn is_throwing(env: Env) -> bool {
9    let mut b: MaybeUninit<bool> = MaybeUninit::zeroed();
10
11    napi::is_exception_pending(env, b.as_mut_ptr()).unwrap();
12
13    b.assume_init()
14}
15
16pub unsafe fn catch_error(env: Env, error: *mut Local) -> bool {
17    if !is_throwing(env) {
18        return false;
19    }
20
21    napi::get_and_clear_last_exception(env, error).unwrap();
22
23    true
24}
25
26pub unsafe fn clear_exception(env: Env) {
27    let mut result = MaybeUninit::uninit();
28    napi::is_exception_pending(env, result.as_mut_ptr()).unwrap();
29
30    if !result.assume_init() {
31        return;
32    }
33
34    let mut result = MaybeUninit::uninit();
35    napi::get_and_clear_last_exception(env, result.as_mut_ptr()).unwrap();
36}
37
38pub unsafe fn throw(env: Env, val: Local) {
39    napi::throw(env, val).unwrap();
40}
41
42pub unsafe fn new_error(env: Env, out: &mut Local, msg: Local) {
43    let mut result = MaybeUninit::uninit();
44    napi::create_error(env, ptr::null_mut(), msg, result.as_mut_ptr()).unwrap();
45
46    *out = result.assume_init();
47}
48
49pub unsafe fn new_type_error(env: Env, out: &mut Local, msg: Local) {
50    let mut result = MaybeUninit::uninit();
51    napi::create_type_error(env, ptr::null_mut(), msg, result.as_mut_ptr()).unwrap();
52
53    *out = result.assume_init();
54}
55
56pub unsafe fn new_range_error(env: Env, out: &mut Local, msg: Local) {
57    let mut result = MaybeUninit::uninit();
58    napi::create_range_error(env, ptr::null_mut(), msg, result.as_mut_ptr()).unwrap();
59
60    *out = result.assume_init();
61}
62
63pub unsafe fn throw_error_from_utf8(env: Env, msg: *const u8, len: i32) {
64    let mut out = MaybeUninit::uninit();
65
66    napi::create_string_utf8(env, msg as *const _, len as usize, out.as_mut_ptr()).unwrap();
67
68    let mut err = MaybeUninit::uninit();
69    napi::create_error(env, ptr::null_mut(), out.assume_init(), err.as_mut_ptr()).unwrap();
70
71    throw(env, err.assume_init());
72}
73
74#[track_caller]
75pub(super) unsafe fn fatal_error(message: &str) -> ! {
76    let location = Location::caller().to_string();
77
78    napi::fatal_error(
79        location.as_ptr().cast(),
80        location.len(),
81        message.as_ptr().cast(),
82        message.len(),
83    );
84
85    unreachable!("Expected napi_fatal_error to exit the process")
86}