Errors
Zig errors become JS exceptions automatically.
That covers most of what you need. The rest of this page is the precise model.
What the bridge does
When your function returns an error, the bridge:
- Reads the error name (
@errorName(e)). - Constructs a JS
Errorwith that name as.message. - Throws it as the result of the JS call.
There is no automatic mapping from Zig errors to JS error subtypes (TypeError, RangeError, etc). Every error becomes a base Error. Type mismatches that are detected during argument conversion are an exception: those are thrown as TypeError by the bridge before your function ever runs.
Throwing a specific JS error type
To throw a TypeError or RangeError from your own code, do it explicitly with env.throw*, then return any error to abort the call:
The throw* family marks an exception as pending on the environment. Returning an error then short-circuits the bridge, which sees the pending exception and lets it propagate without overwriting it. The Zig error you return is just a way to bail out; the actual JS error is the RangeError you constructed.
The same applies to env.throwError(msg), env.throwTypeError(msg), and env.throwValue(val) for throwing an existing JS value.
Catching specific N-API failures
napi.Error is the @teakit/napi error set. It covers every distinct N-API failure mode:
error.QueueFullerror.Closingerror.PendingExceptionerror.StringExpectederror.NumberExpected- ...and so on
Use it when you want to handle a specific failure mode rather than propagate everything:
The full set is documented in the Error reference.
Errors from workers and async
A worker's resolve function rejects the JS promise when it returns an error:
See Workers for the rest.
What you cannot catch in JS
Zig panics (index out of bounds, unreachable, integer overflow in debug builds) are not Zig errors. They abort the process.
A panic in Zig code, especially on a worker thread, crashes the entire Node.js process. Errors are values; panics are bugs. Use if, try, and explicit error returns for anything that can fail at runtime.
In production builds (ReleaseFast, ReleaseSmall), undefined behavior in Zig will not panic; it will silently misbehave. Test in Debug and ReleaseSafe to catch these.