diff --git a/.changeset/clean-ligers-reply.md b/.changeset/clean-ligers-reply.md new file mode 100644 index 00000000..bbedf0e8 --- /dev/null +++ b/.changeset/clean-ligers-reply.md @@ -0,0 +1,5 @@ +--- +'nxjs-runtime': patch +--- + +Log unhandled errors / promise rejections to the debug log file diff --git a/source/error.c b/source/error.c index c7317856..bcd6d2ba 100644 --- a/source/error.c +++ b/source/error.c @@ -6,14 +6,13 @@ void print_js_error(JSContext *ctx) const char *exception_str = JS_ToCString(ctx, exception_val); printf("%s\n", exception_str); fprintf(stderr, "%s\n", exception_str); - fflush(stderr); JS_FreeCString(ctx, exception_str); JSValue stack_val = JS_GetPropertyStr(ctx, exception_val, "stack"); const char *stack_str = JS_ToCString(ctx, stack_val); printf("%s\n", stack_str); fprintf(stderr, "%s\n", stack_str); - fflush(stderr); + JS_FreeCString(ctx, stack_str); JS_FreeValue(ctx, exception_val); JS_FreeValue(ctx, stack_val); @@ -23,6 +22,20 @@ void nx_emit_error_event(JSContext *ctx) { JSValue exception_val = JS_GetException(ctx); nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); + + // Print the error to stderr so that it ends up in the log file + const char *exception_str = JS_ToCString(ctx, exception_val); + fprintf(stderr, "Uncaught %s\n", exception_str); + JS_FreeCString(ctx, exception_str); + + JSValue stack_val = JS_GetPropertyStr(ctx, exception_val, "stack"); + if (!JS_IsUndefined(stack_val)) { + const char *stack_str = JS_ToCString(ctx, stack_val); + fprintf(stderr, "%s\n", stack_str); + JS_FreeCString(ctx, stack_str); + JS_FreeValue(ctx, stack_val); + } + JSValueConst args[] = {exception_val}; JSValue ret_val = JS_Call(ctx, nx_ctx->error_handler, JS_NULL, 1, args); if (JS_IsException(ret_val)) @@ -52,6 +65,20 @@ void nx_promise_rejection_handler(JSContext *ctx, JSValueConst promise, JS_BOOL is_handled, void *opaque) { nx_context_t *nx_ctx = JS_GetContextOpaque(ctx); + + // Print the error to stderr so that it ends up in the log file + const char *exception_str = JS_ToCString(ctx, reason); + fprintf(stderr, "Uncaught (in promise) %s\n", exception_str); + JS_FreeCString(ctx, exception_str); + + JSValue stack_val = JS_GetPropertyStr(ctx, reason, "stack"); + if (!JS_IsUndefined(stack_val)) { + const char *stack_str = JS_ToCString(ctx, stack_val); + fprintf(stderr, "%s\n", stack_str); + JS_FreeCString(ctx, stack_str); + JS_FreeValue(ctx, stack_val); + } + JSValueConst args[] = {promise, reason}; JSValue ret_val = JS_Call(ctx, nx_ctx->unhandled_rejection_handler, JS_NULL, 2, args); if (JS_IsException(ret_val))