Skip to content

Commit

Permalink
Add "error" global event when an Error is not caught
Browse files Browse the repository at this point in the history
  • Loading branch information
TooTallNate committed Oct 21, 2023
1 parent 4eff094 commit 436f4d2
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/spotty-rockets-report.md
@@ -0,0 +1,5 @@
---
'nxjs-runtime': patch
---

Add "error" global event when an Error is not caught
11 changes: 8 additions & 3 deletions packages/runtime/src/$.ts
@@ -1,13 +1,18 @@
import type { MemoryDescriptor, Memory } from './wasm';

export interface Init {
onUnhandledRejection(
fn: (promise: Promise<unknown>, reason: any) => void
): void;
// battery.c
batteryInit(): void;
batteryInitClass(c: any): void;
batteryExit(): void;

// error.c
onError(fn: (err: any) => void): void;
onUnhandledRejection(
fn: (promise: Promise<unknown>, reason: any) => void
): void;

// wasm.c
wasmCallFunc(f: any, ...args: unknown[]): unknown;
wasmMemNew(descriptor: MemoryDescriptor): Memory;
wasmTableGet(t: any, i: number): Memory;
Expand Down
11 changes: 11 additions & 0 deletions packages/runtime/src/index.ts
Expand Up @@ -11,6 +11,7 @@ import {
} from './timers';
import { console } from './console';
import {
ErrorEvent,
KeyboardEvent,
TouchEvent,
UIEvent,
Expand Down Expand Up @@ -131,6 +132,16 @@ def(
);
def('dispatchEvent', EventTarget.prototype.dispatchEvent.bind(globalThis));

$.onError((e) => {
const ev = new ErrorEvent('error', {
error: e,
});
dispatchEvent(ev);
if (!ev.defaultPrevented) {
console.error('Uncaught', e);
}
});

$.onUnhandledRejection((p, r) => {
const ev = new PromiseRejectionEvent('unhandledrejection', {
promise: p,
Expand Down
28 changes: 28 additions & 0 deletions source/error.c
Expand Up @@ -20,6 +20,33 @@ void print_js_error(JSContext *ctx)
JS_FreeValue(ctx, exception_val);
}

int nx_emit_error_event(JSContext *ctx)
{
JSValue exception_val = JS_GetException(ctx);

nx_context_t *nx_ctx = JS_GetContextOpaque(ctx);
JSValueConst args[] = {exception_val};
JSValue ret_val = JS_Call(ctx, nx_ctx->onerror_handler, JS_NULL, 1, args);

// TODO: what should happen here?
// if (JS_IsException(ret_val))
//{
// print_js_error(ctx);
//}

JS_FreeValue(ctx, exception_val);
JS_FreeValue(ctx, ret_val);

return 0;
}

static JSValue nx_set_onerror_handler(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
nx_context_t *nx_ctx = JS_GetContextOpaque(ctx);
nx_ctx->onerror_handler = JS_DupValue(ctx, argv[0]);
return JS_UNDEFINED;
}

static JSValue nx_set_unhandled_rejection_handler(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
nx_context_t *nx_ctx = JS_GetContextOpaque(ctx);
Expand All @@ -42,6 +69,7 @@ void nx_promise_rejection_handler(JSContext *ctx, JSValueConst promise,
}

static const JSCFunctionListEntry function_list[] = {
JS_CFUNC_DEF("onError", 1, nx_set_onerror_handler),
JS_CFUNC_DEF("onUnhandledRejection", 1, nx_set_unhandled_rejection_handler),
};

Expand Down
2 changes: 2 additions & 0 deletions source/error.h
Expand Up @@ -3,6 +3,8 @@

void print_js_error(JSContext *ctx);

int nx_emit_error_event(JSContext *ctx);

void nx_promise_rejection_handler(JSContext *ctx, JSValueConst promise,
JSValueConst reason,
JS_BOOL is_handled, void *opaque);
Expand Down
8 changes: 6 additions & 2 deletions source/main.c
Expand Up @@ -460,6 +460,7 @@ int main(int argc, char *argv[])
nx_context_t *nx_ctx = malloc(sizeof(nx_context_t));
memset(nx_ctx, 0, sizeof(nx_context_t));
nx_ctx->thpool = thpool_init(4);
nx_ctx->onerror_handler = JS_UNDEFINED;
nx_ctx->unhandled_rejection_handler = JS_UNDEFINED;
pthread_mutex_init(&(nx_ctx->async_done_mutex), NULL);
JS_SetContextOpaque(ctx, nx_ctx);
Expand Down Expand Up @@ -603,7 +604,8 @@ int main(int argc, char *argv[])
JSValue user_code_result = JS_Eval(ctx, user_code, user_code_size, js_path, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
if (JS_IsException(user_code_result))
{
print_js_error(ctx);
// print_js_error(ctx);
nx_emit_error_event(ctx);
had_error = 1;
}
else
Expand All @@ -612,7 +614,8 @@ int main(int argc, char *argv[])
user_code_result = JS_EvalFunction(ctx, user_code_result);
if (JS_IsException(user_code_result))
{
print_js_error(ctx);
// print_js_error(ctx);
nx_emit_error_event(ctx);
had_error = 1;
}
}
Expand Down Expand Up @@ -714,6 +717,7 @@ int main(int argc, char *argv[])
JS_FreeValue(ctx, native_obj);
JS_FreeValue(ctx, switch_obj);
JS_FreeValue(ctx, global_obj);
JS_FreeValue(ctx, nx_ctx->onerror_handler);
JS_FreeValue(ctx, nx_ctx->unhandled_rejection_handler);

JS_FreeContext(ctx);
Expand Down
1 change: 1 addition & 0 deletions source/types.h
Expand Up @@ -58,6 +58,7 @@ typedef struct
FT_Library ft_library;
HidVibrationDeviceHandle vibration_device_handles[2];
IM3Environment wasm_env;
JSValue onerror_handler;
JSValue unhandled_rejection_handler;
} nx_context_t;

Expand Down

0 comments on commit 436f4d2

Please sign in to comment.