Struct napi::bindgen_prelude::Error

source ·
pub struct Error {
    pub status: Status,
    pub reason: String,
    /* private fields */
}
Expand description

Represent JsError. Return this Error in js_function, napi-rs will throw it as JsError for you. If you want throw it as TypeError or RangeError, you can use JsTypeError/JsRangeError::from(Error).throw_into(env)

Fields§

§status: Status§reason: String

Implementations§

Examples found in repository?
src/error.rs (line 61)
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  fn custom<T: Display>(msg: T) -> Self {
    Error::new(Status::InvalidArg, msg.to_string())
  }
}

#[cfg(feature = "serde-json")]
impl de::Error for Error {
  fn custom<T: Display>(msg: T) -> Self {
    Error::new(Status::InvalidArg, msg.to_string())
  }
}

#[cfg(feature = "serde-json")]
impl From<SerdeJSONError> for Error {
  fn from(value: SerdeJSONError) -> Self {
    Error::new(Status::InvalidArg, format!("{}", value))
  }
}

impl From<JsUnknown> for Error {
  fn from(value: JsUnknown) -> Self {
    let mut result = std::ptr::null_mut();
    let status = unsafe { sys::napi_create_reference(value.0.env, value.0.value, 0, &mut result) };
    if status != sys::Status::napi_ok {
      return Error::new(Status::from(status), "".to_owned());
    }
    Self {
      status: Status::GenericFailure,
      reason: "".to_string(),
      maybe_raw: result,
      maybe_env: value.0.env,
    }
  }
}

#[cfg(feature = "anyhow")]
impl From<anyhow::Error> for Error {
  fn from(value: anyhow::Error) -> Self {
    Error::new(Status::GenericFailure, format!("{}", value))
  }
}

impl fmt::Display for Error {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    if !self.reason.is_empty() {
      write!(f, "{:?}, {}", self.status, self.reason)
    } else {
      write!(f, "{:?}", self.status)
    }
  }
}

impl Error {
  pub fn new(status: Status, reason: String) -> Self {
    Error {
      status,
      reason,
      maybe_raw: ptr::null_mut(),
      maybe_env: ptr::null_mut(),
    }
  }

  pub fn from_status(status: Status) -> Self {
    Error {
      status,
      reason: "".to_owned(),
      maybe_raw: ptr::null_mut(),
      maybe_env: ptr::null_mut(),
    }
  }

  pub fn from_reason<T: Into<String>>(reason: T) -> Self {
    Error {
      status: Status::GenericFailure,
      reason: reason.into(),
      maybe_raw: ptr::null_mut(),
      maybe_env: ptr::null_mut(),
    }
  }
}

impl From<std::ffi::NulError> for Error {
  fn from(error: std::ffi::NulError) -> Self {
    Error {
      status: Status::GenericFailure,
      reason: format!("{}", error),
      maybe_raw: ptr::null_mut(),
      maybe_env: ptr::null_mut(),
    }
  }
}

impl From<std::io::Error> for Error {
  fn from(error: std::io::Error) -> Self {
    Error {
      status: Status::GenericFailure,
      reason: format!("{}", error),
      maybe_raw: ptr::null_mut(),
      maybe_env: ptr::null_mut(),
    }
  }
}

impl Drop for Error {
  fn drop(&mut self) {
    if !self.maybe_env.is_null() && !self.maybe_raw.is_null() {
      let delete_reference_status =
        unsafe { sys::napi_delete_reference(self.maybe_env, self.maybe_raw) };
      debug_assert!(
        delete_reference_status == sys::Status::napi_ok,
        "Delete Error Reference failed"
      );
    }
  }
}

#[derive(Clone, Debug)]
pub struct ExtendedErrorInfo {
  pub message: String,
  pub engine_reserved: *mut c_void,
  pub engine_error_code: u32,
  pub error_code: Status,
}

impl TryFrom<sys::napi_extended_error_info> for ExtendedErrorInfo {
  type Error = Error;

  fn try_from(value: sys::napi_extended_error_info) -> Result<Self> {
    Ok(Self {
      message: unsafe {
        CString::from_raw(value.error_message as *mut c_char)
          .into_string()
          .map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?
      },
      engine_error_code: value.engine_error_code,
      engine_reserved: value.engine_reserved,
      error_code: Status::from(value.error_code),
    })
  }
}

pub struct JsError(Error);

#[cfg(feature = "anyhow")]
impl From<anyhow::Error> for JsError {
  fn from(value: anyhow::Error) -> Self {
    JsError(Error::new(Status::GenericFailure, value.to_string()))
  }
More examples
Hide additional examples
src/js_values/string/utf8.rs (line 17)
14
15
16
17
18
  pub fn as_str(&self) -> Result<&str> {
    unsafe { CStr::from_ptr(self.buf.as_ptr()) }
      .to_str()
      .map_err(|e| Error::new(Status::InvalidArg, format!("{}", e)))
  }
src/js_values/string/utf16.rs (line 14)
12
13
14
15
16
17
18
  pub fn as_str(&self) -> Result<String> {
    if let Some((_, prefix)) = self.as_slice().split_last() {
      String::from_utf16(prefix).map_err(|e| Error::new(Status::InvalidArg, format!("{}", e)))
    } else {
      Ok(String::new())
    }
  }
src/bindgen_runtime/js_values/nil.rs (lines 25-28)
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
    match type_of!(env, napi_val) {
      Ok(ValueType::Null) => Ok(Null),
      _ => Err(Error::new(
        Status::InvalidArg,
        "Value is not null".to_owned(),
      )),
    }
  }
}

impl ToNapiValue for Null {
  unsafe fn to_napi_value(env: sys::napi_env, _val: Self) -> Result<sys::napi_value> {
    let mut ret = ptr::null_mut();

    check_status!(
      unsafe { sys::napi_get_null(env, &mut ret) },
      "Failed to create napi null value"
    )?;

    Ok(ret)
  }
}

impl TypeName for Undefined {
  fn type_name() -> &'static str {
    "undefined"
  }

  fn value_type() -> ValueType {
    ValueType::Undefined
  }
}

impl ValidateNapiValue for Undefined {}

impl FromNapiValue for Undefined {
  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
    match type_of!(env, napi_val) {
      Ok(ValueType::Undefined) => Ok(()),
      _ => Err(Error::new(
        Status::InvalidArg,
        "Value is not undefined".to_owned(),
      )),
    }
  }
src/call_context.rs (lines 51-54)
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  pub fn get<ArgType: FromNapiValue>(&self, index: usize) -> Result<ArgType> {
    if index >= self.arg_len() {
      Err(Error::new(
        Status::GenericFailure,
        "Arguments index out of range".to_owned(),
      ))
    } else {
      unsafe { ArgType::from_napi_value(self.env.0, self.args[index]) }
    }
  }

  pub fn try_get<ArgType: NapiValue + TypeName + FromNapiValue>(
    &self,
    index: usize,
  ) -> Result<Either<ArgType, JsUndefined>> {
    if index >= self.arg_len() {
      Err(Error::new(
        Status::GenericFailure,
        "Arguments index out of range".to_owned(),
      ))
    } else if index < self.length {
      unsafe { ArgType::from_raw(self.env.0, self.args[index]) }.map(Either::A)
    } else {
      self.env.get_undefined().map(Either::B)
    }
  }
src/bindgen_runtime/js_values/promise.rs (line 168)
164
165
166
167
168
169
170
171
172
  fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    match self.value.as_mut().poll(cx) {
      Poll::Pending => Poll::Pending,
      Poll::Ready(v) => Poll::Ready(
        v.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))
          .and_then(|v| unsafe { *Box::from_raw(v) }.map_err(Error::from)),
      ),
    }
  }
Examples found in repository?
src/env.rs (lines 584-593)
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
          unsafe extern "C" fn trampoline<R: NapiRaw, F: Fn(CallContext<'_>) -> Result<R>>(
            raw_env: sys::napi_env,
            cb_info: sys::napi_callback_info,
          ) -> sys::napi_value {
            use ::std::panic::{self, AssertUnwindSafe};
            panic::catch_unwind(AssertUnwindSafe(|| {
              let (raw_this, ref raw_args, closure_data_ptr) = {
                let argc = {
                  let mut argc = 0;
                  let status = unsafe {
                    sys::napi_get_cb_info(
                      raw_env,
                      cb_info,
                      &mut argc,
                      ptr::null_mut(),
                      ptr::null_mut(),
                      ptr::null_mut(),
                    )
                  };
                  debug_assert!(
                    Status::from(status) == Status::Ok,
                    "napi_get_cb_info failed"
                  );
                  argc
                };
                let mut raw_args = vec![ptr::null_mut(); argc];
                let mut raw_this = ptr::null_mut();
                let mut closure_data_ptr = ptr::null_mut();

                let status = unsafe {
                  sys::napi_get_cb_info(
                    raw_env,
                    cb_info,
                    &mut { argc },
                    raw_args.as_mut_ptr(),
                    &mut raw_this,
                    &mut closure_data_ptr,
                  )
                };
                debug_assert!(
                  Status::from(status) == Status::Ok,
                  "napi_get_cb_info failed"
                );
                (raw_this, raw_args, closure_data_ptr)
              };

              let closure: &F = unsafe {
                closure_data_ptr
                  .cast::<F>()
                  .as_ref()
                  .expect("`napi_get_cb_info` should have yielded non-`NULL` assoc data")
              };
              let env = &mut unsafe { Env::from_raw(raw_env) };
              let ctx = CallContext::new(env, cb_info, raw_this, raw_args, raw_args.len());
              closure(ctx).map(|ret: R| unsafe { ret.raw() })
            }))
            .map_err(|e| {
              Error::from_reason(format!(
                "panic from Rust code: {}",
                if let Some(s) = e.downcast_ref::<String>() {
                  s
                } else if let Some(s) = e.downcast_ref::<&str>() {
                  s
                } else {
                  "<no error message>"
                },
              ))
            })
            .and_then(|v| v)
            .unwrap_or_else(|e| {
              unsafe { JsError::from(e).throw_into(raw_env) };
              ptr::null_mut()
            })
          }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
Executes the destructor for this type. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Used when a Serialize implementation encounters any error while serializing a type. Read more
Raised when there is general error when deserializing a type. Read more
Raised when a Deserialize receives a type different from what it was expecting. Read more
Raised when a Deserialize receives a value of the right type but that is wrong for some other reason. Read more
Raised when deserializing a sequence or map and the input data contains too many or too few elements. Read more
Raised when a Deserialize enum type received a variant with an unrecognized name.
Raised when a Deserialize struct type received a field with an unrecognized name.
Raised when a Deserialize struct type expected to receive a required field with a particular name but that field was not present in the input.
Raised when a Deserialize struct type received more than one of the same field.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Safety Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to provide by using demand. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.