diff --git a/quickjs.c b/quickjs.c index f076d496e..54df4c379 100644 --- a/quickjs.c +++ b/quickjs.c @@ -6673,6 +6673,43 @@ static JSValue JS_ThrowError(JSContext *ctx, JSErrorEnum error_num, return JS_ThrowError2(ctx, error_num, fmt, ap, add_backtrace); } +JSValue __attribute__((format(printf, 2, 3))) JS_ThrowPlainError(JSContext *ctx, const char *fmt, ...) +{ + JSRuntime *rt = ctx->rt; + JSStackFrame *sf; + BOOL add_backtrace; + JSValue val, ret; + char buf[256]; + va_list ap; + + sf = rt->current_stack_frame; + add_backtrace = !rt->in_out_of_memory && + (!sf || (JS_GetFunctionBytecode(sf->cur_func) == NULL)); + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + val = JS_NewError(ctx); + if (unlikely(JS_IsException(val))) { + /* out of memory: throw JS_NULL to avoid recursing */ + val = JS_NULL; + } else { + JSValue msg = JS_NewString(ctx, buf); + if (JS_IsException(msg)) + msg = JS_NewString(ctx, "Invalid error message"); + if (!JS_IsException(msg)) { + JS_DefinePropertyValue(ctx, val, JS_ATOM_message, msg, + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } + } + if (add_backtrace) { + build_backtrace(ctx, val, NULL, 0, 0, 0); + } + ret = JS_Throw(ctx, val); + return ret; +} + JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) { JSValue val; diff --git a/quickjs.h b/quickjs.h index cb5d52803..d4834934f 100644 --- a/quickjs.h +++ b/quickjs.h @@ -580,6 +580,7 @@ JS_EXTERN JSValue JS_GetException(JSContext *ctx); JS_EXTERN JS_BOOL JS_IsError(JSContext *ctx, JSValue val); JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx); JS_EXTERN JSValue JS_NewError(JSContext *ctx); +JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowPlainError(JSContext *ctx, const char *fmt, ...); JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...); JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...); JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);