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}