# Error handling

Error handling represents one of the most important considerations when
implementing a Node.js native add-on. When an error occurs in your C++ code you
have to handle and dispatch it correctly. **node-addon-api** uses return values and
JavaScript exceptions for error handling. You can choose return values or
exception handling based on the mechanism that works best for your add-on.

The `Napi::Error` is a persistent reference (for more info see: [`Napi::ObjectReference`](object_reference.md))
to a JavaScript error object. Use of this class depends on whether C++
exceptions are enabled at compile time.

If C++ exceptions are enabled (for more info see: [Setup](setup.md)), then the
`Napi::Error` class extends `std::exception` and enables integrated
error-handling for C++ exceptions and JavaScript exceptions.

Note, that due to limitations of the Node-API, if one attempts to cast the error object wrapping a primitive inside a C++ addon, the wrapped object
will be received instead. (With property `4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal` containing the primitive value thrown)

The following sections explain the approach for each case:

- [Handling Errors With C++ Exceptions](#exceptions)
- [Handling Errors With Maybe Type and C++ Exceptions Disabled](#noexceptions-maybe)
- [Handling Errors Without C++ Exceptions](#noexceptions)

<a name="exceptions"></a>

In most cases when an error occurs, the addon should do whatever cleanup is possible
and then return to JavaScript so that the error can be propagated. In less frequent
cases the addon may be able to recover from the error, clear the error and then
continue.

## Handling Errors With C++ Exceptions

When C++ exceptions are enabled try/catch can be used to catch exceptions thrown
from calls to JavaScript and then they can either be handled or rethrown before
returning from a native method.

If a node-addon-api call fails without executing any JavaScript code (for example due to
an invalid argument), then node-addon-api automatically converts and throws
the error as a C++ exception of type `Napi::Error`.

If a JavaScript function called by C++ code via node-addon-api throws a JavaScript
exception, then node-addon-api automatically converts and throws it as a C++
exception of type `Napi::Error` on return from the JavaScript code to the native
method.

If a C++ exception of type `Napi::Error` escapes from a Node-API C++ callback, then
the Node-API wrapper automatically converts and throws it as a JavaScript exception.

If other types of C++ exceptions are thrown, node-addon-api will either abort
the process or wrap the exception in an `Napi::Error` in order to throw it as a
JavaScript exception. This behavior is determined by which node-gyp dependency
used:

- When using the `node_addon_api_except` dependency, only `Napi::Error` objects
  will be handled.
- When using the `node_addon_api_except_all` dependency, all exceptions will be
handled. For exceptions derived from `std::exception`, an `Napi::Error` will be
created with the message of the exception's `what()` member function. For all
other exceptions, an `Napi::Error` will be created with a generic error message.

On return from a native method, node-addon-api will automatically convert a pending
`Napi::Error` C++ exception to a JavaScript exception.

When C++ exceptions are enabled try/catch can be used to catch exceptions thrown
from calls to JavaScript and then they can either be handled or rethrown before
returning from a native method.

## Examples with C++ exceptions enabled

### Throwing a C++ exception

```cpp
Env env = ...
throw Napi::Error::New(env, "Example exception");
// other C++ statements
// ...
```

The statements following the throw statement will not be executed. The exception
will bubble up as a C++ exception of type `Napi::Error`, until it is either caught
while still in C++, or else automatically propagated as a JavaScript exception
when returning to JavaScript.

### Propagating a Node-API C++ exception

```cpp
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
// other C++ statements
// ...
```

The C++ statements following the call to the JavaScript function will not be
executed. The exception will bubble up as a C++ exception of type `Napi::Error`,
until it is either caught while still in C++, or else automatically propagated as
a JavaScript exception when returning to JavaScript.

### Handling a Node-API C++ exception

```cpp
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Napi::Value result;
try {
    result = jsFunctionThatThrows({ arg1, arg2 });
} catch (const Error& e) {
    cerr << "Caught JavaScript exception: " + e.what();
}
```

Since the exception was caught here, it will not be propagated as a JavaScript
exception.

<a name="noexceptions-maybe"></a>

## Handling Errors With Maybe Type and C++ Exceptions Disabled

If C++ exceptions are disabled (for more info see: [Setup](setup.md)), then the
`Napi::Error` class does not extend `std::exception`. This means that any calls to
node-addon-api functions do not throw a C++ exceptions. Instead, these node-api
functions that call into JavaScript are returning with `Maybe` boxed values.
In that case, the calling side should convert the `Maybe` boxed values with
checks to ensure that the call did succeed and therefore no exception is pending.
If the check fails, that is to say, the returning value is _empty_, the calling
side should determine what to do with `env.GetAndClearPendingException()` before
attempting to call another node-api (for more info see: [Env](env.md)).

The conversion from the `Maybe` boxed value to the actual return value is
enforced by compilers so that the exceptions must be properly handled before
continuing.

## Examples with Maybe Type and C++ exceptions disabled

### Throwing a JS exception

```cpp
Napi::Env env = ...
Napi::Error::New(env, "Example exception").ThrowAsJavaScriptException();
return;
```

After throwing a JavaScript exception, the code should generally return
immediately from the native callback, after performing any necessary cleanup.

### Propagating a Node-API JS exception

```cpp
Napi::Env env = ...
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Maybe<Napi::Value> maybeResult = jsFunctionThatThrows({ arg1, arg2 });
Napi::Value result;
if (!maybeResult.To(&result)) {
    // The Maybe is empty, calling into js failed, cleaning up...
    // It is recommended to return an empty Maybe if the procedure failed.
    return result;
}
```

If `maybeResult.To(&result)` returns false a JavaScript exception is pending.
To let the exception propagate, the code should generally return immediately
from the native callback, after performing any necessary cleanup.

### Handling a Node-API JS exception

```cpp
Napi::Env env = ...
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Maybe<Napi::Value> maybeResult = jsFunctionThatThrows({ arg1, arg2 });
if (maybeResult.IsNothing()) {
    Napi::Error e = env.GetAndClearPendingException();
    cerr << "Caught JavaScript exception: " + e.Message();
}
```

Since the exception was cleared here, it will not be propagated as a JavaScript
exception after the native callback returns.

<a name="noexceptions"></a>

## Handling Errors Without C++ Exceptions

If C++ exceptions are disabled (for more info see: [Setup](setup.md)), then the
`Napi::Error` class does not extend `std::exception`. This means that any calls to
node-addon-api function do not throw a C++ exceptions. Instead, it raises
_pending_ JavaScript exceptions and returns an _empty_ `Napi::Value`.
The calling code should check `env.IsExceptionPending()` before attempting to use a
returned value, and may use methods on the `Napi::Env` class
to check for, get, and clear a pending JavaScript exception (for more info see: [Env](env.md)).
If the pending exception is not cleared, it will be thrown when the native code
returns to JavaScript.

## Examples with C++ exceptions disabled

### Throwing a JS exception

```cpp
Napi::Env env = ...
Napi::Error::New(env, "Example exception").ThrowAsJavaScriptException();
return;
```

After throwing a JavaScript exception, the code should generally return
immediately from the native callback, after performing any necessary cleanup.

### Propagating a Node-API JS exception

```cpp
Napi::Env env = ...
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
if (env.IsExceptionPending()) {
    Error e = env.GetAndClearPendingException();
    return e.Value();
}
```

If env.IsExceptionPending() returns true a JavaScript exception is pending. To
let the exception propagate, the code should generally return immediately from
the native callback, after performing any necessary cleanup.

### Handling a Node-API JS exception

```cpp
Napi::Env env = ...
Napi::Function jsFunctionThatThrows = someValue.As<Napi::Function>();
Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
if (env.IsExceptionPending()) {
    Napi::Error e = env.GetAndClearPendingException();
    cerr << "Caught JavaScript exception: " + e.Message();
}
```

Since the exception was cleared here, it will not be propagated as a JavaScript
exception after the native callback returns.

## Calling Node-API directly from a **node-addon-api** addon

**node-addon-api** provides macros for throwing errors in response to non-OK
`napi_status` results when calling [Node-API](https://nodejs.org/docs/latest/api/n-api.html)
functions from within a native addon. These macros are defined differently
depending on whether C++ exceptions are enabled or not, but are available for
use in either case.

### `NAPI_THROW(e, ...)`

This macro accepts a `Napi::Error`, throws it, and returns the value given as
the last parameter. If C++ exceptions are enabled (by defining
`NAPI_CPP_EXCEPTIONS` during the build), the return value will be ignored.

### `NAPI_THROW_IF_FAILED(env, status, ...)`

This macro accepts a `Napi::Env` and a `napi_status`. It constructs an error
from the `napi_status`, throws it, and returns the value given as the last
parameter. If C++ exceptions are enabled (by defining `NAPI_CPP_EXCEPTIONS`
during the build), the return value will be ignored.

### `NAPI_THROW_IF_FAILED_VOID(env, status)`

This macro accepts a `Napi::Env` and a `napi_status`. It constructs an error
from the `napi_status`, throws it, and returns.

### `NAPI_FATAL_IF_FAILED(status, location, message)`

This macro accepts a `napi_status`, a C string indicating the location where the
error occurred, and a second C string for the message to display.
