Distinguishing Lifetimes of napi_value and napi_ref
napi_valueinstances are automatically tracked and retained within the currentHandleScope. Explicit scope management is typically unnecessary—except in asynchronous completion callbacks (e.g., those invoked afteruv_queue_work). In such contexts, a dedicatedHandleScopemust be establisehd before handling values.napi_refobjects require explicit lifetime control. Developers must callnapi_delete_reference()to release them; failure to do so results in memory leaks.
Diagnosing Non-napi_ok Return Codes from Node-API Calls
When a Node-API function returns a status other than napi_ok, follow this structured diagnostic path:
-
Null Argument Validation: Most functions perform early null checks on inputs. Common macros include:
CHECK_ENV(env); // Ensures environment pointer is valid CHECK_ARG(arg, index); // Verifies argument at position `index` is non-null -
Type Consistency Checks: Some APIs enforce strict JS-to-C type correspondence. For instance,
napi_get_value_double()expects the inputnapi_valueto represent a JavaScriptNumber. A typical guard looks like:napi_valuetype type; napi_typeof(env, value, &type); if (type != napi_number) { return napi_number_expected; } -
Runtime Outcome Validation: Functions that trigger JavaScript execution—such as
napi_call_function()—must inspect the result for runtime exceptions. Example:napi_value result; napi_status status = napi_call_function(env, recv, func, argv, argc, &result); if (status != napi_ok) { // Check for pending exception before returning bool has_exception; napi_is_exception_pending(env, &has_exception); if (has_exception) { return napi_pending_exception; } return status; } -
Context-Specific Status Interpretation: Certain error codes (e.g.,
napi_invalid_arg,napi_generic_failure) depend on internal implementation details. Consult the specific API’s documentation to determine under which conditions each code arises, then trace back through input state, engine context, and rseource availability.