Skip to content

Commit fcc20c6

Browse files
authored
Add JS_New{Internal,Plain,Range,Reference,Syntax,Type}Error (#1131)
Fixes: #1129
1 parent 814d43a commit fcc20c6

File tree

3 files changed

+105
-77
lines changed

3 files changed

+105
-77
lines changed

api-test.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <stdlib.h>
66
#include <string.h>
77
#include "quickjs.h"
8+
#include "cutils.h"
89

910
#define MAX_TIME 10
1011

@@ -506,6 +507,44 @@ static void dump_memory_usage(void)
506507
JS_FreeRuntime(rt);
507508
}
508509

510+
static void new_errors(void)
511+
{
512+
typedef struct {
513+
const char name[16];
514+
JSValue (*func)(JSContext *, const char *, ...);
515+
} Entry;
516+
static const Entry entries[] = {
517+
{"Error", JS_NewPlainError},
518+
{"InternalError", JS_NewInternalError},
519+
{"RangeError", JS_NewRangeError},
520+
{"ReferenceError", JS_NewReferenceError},
521+
{"SyntaxError", JS_NewSyntaxError},
522+
{"TypeError", JS_NewTypeError},
523+
};
524+
const Entry *e;
525+
526+
JSRuntime *rt = JS_NewRuntime();
527+
JSContext *ctx = JS_NewContext(rt);
528+
for (e = entries; e < endof(entries); e++) {
529+
JSValue obj = (*e->func)(ctx, "the %s", "needle");
530+
assert(!JS_IsException(obj));
531+
assert(JS_IsObject(obj));
532+
assert(JS_IsError(ctx, obj));
533+
const char *haystack = JS_ToCString(ctx, obj);
534+
char needle[256];
535+
snprintf(needle, sizeof(needle), "%s: the needle", e->name);
536+
assert(strstr(haystack, needle));
537+
JS_FreeCString(ctx, haystack);
538+
JSValue stack = JS_GetPropertyStr(ctx, obj, "stack");
539+
assert(!JS_IsException(stack));
540+
assert(JS_IsString(stack));
541+
JS_FreeValue(ctx, stack);
542+
JS_FreeValue(ctx, obj);
543+
}
544+
JS_FreeContext(ctx);
545+
JS_FreeRuntime(rt);
546+
}
547+
509548
int main(void)
510549
{
511550
sync_call();
@@ -518,5 +557,6 @@ int main(void)
518557
weak_map_gc_check();
519558
promise_hook();
520559
dump_memory_usage();
560+
new_errors();
521561
return 0;
522562
}

quickjs.c

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6947,8 +6947,8 @@ JSValue JS_NewError(JSContext *ctx)
69476947
return obj;
69486948
}
69496949

6950-
static JSValue JS_MakeError(JSContext *ctx, JSErrorEnum error_num,
6951-
const char *message, bool add_backtrace)
6950+
static JSValue JS_MakeError2(JSContext *ctx, JSErrorEnum error_num,
6951+
bool add_backtrace, const char *message)
69526952
{
69536953
JSValue obj, msg;
69546954

@@ -6972,16 +6972,24 @@ static JSValue JS_MakeError(JSContext *ctx, JSErrorEnum error_num,
69726972
return obj;
69736973
}
69746974

6975-
/* fmt and arguments may be pure ASCII or UTF-8 encoded contents */
69766975
static JSValue JS_PRINTF_FORMAT_ATTR(4, 0)
6977-
JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num,
6978-
bool add_backtrace, JS_PRINTF_FORMAT const char *fmt, va_list ap)
6976+
JS_MakeError(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace,
6977+
JS_PRINTF_FORMAT const char *fmt, va_list ap)
69796978
{
69806979
char buf[256];
6981-
JSValue obj;
69826980

69836981
vsnprintf(buf, sizeof(buf), fmt, ap);
6984-
obj = JS_MakeError(ctx, error_num, buf, add_backtrace);
6982+
return JS_MakeError2(ctx, error_num, add_backtrace, buf);
6983+
}
6984+
6985+
/* fmt and arguments may be pure ASCII or UTF-8 encoded contents */
6986+
static JSValue JS_PRINTF_FORMAT_ATTR(4, 0)
6987+
JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace,
6988+
JS_PRINTF_FORMAT const char *fmt, va_list ap)
6989+
{
6990+
JSValue obj;
6991+
6992+
obj = JS_MakeError(ctx, error_num, add_backtrace, fmt, ap);
69856993
if (unlikely(JS_IsException(obj))) {
69866994
/* out of memory: throw JS_NULL to avoid recursing */
69876995
obj = JS_NULL;
@@ -7004,38 +7012,45 @@ JS_ThrowError(JSContext *ctx, JSErrorEnum error_num,
70047012
return JS_ThrowError2(ctx, error_num, add_backtrace, fmt, ap);
70057013
}
70067014

7007-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7008-
{
7009-
JSValue val;
7010-
va_list ap;
7011-
7012-
va_start(ap, fmt);
7013-
val = JS_ThrowError(ctx, JS_PLAIN_ERROR, fmt, ap);
7014-
va_end(ap);
7015-
return val;
7016-
}
7017-
7018-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7019-
{
7020-
JSValue val;
7021-
va_list ap;
7022-
7023-
va_start(ap, fmt);
7024-
val = JS_ThrowError(ctx, JS_SYNTAX_ERROR, fmt, ap);
7025-
va_end(ap);
7026-
return val;
7027-
}
7028-
7029-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7030-
{
7031-
JSValue val;
7032-
va_list ap;
7033-
7034-
va_start(ap, fmt);
7035-
val = JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap);
7036-
va_end(ap);
7037-
return val;
7038-
}
7015+
#define JS_ERROR_MAP(X) \
7016+
X(Internal, INTERNAL) \
7017+
X(Plain, PLAIN) \
7018+
X(Range, RANGE) \
7019+
X(Reference, REFERENCE) \
7020+
X(Syntax, SYNTAX) \
7021+
X(Type, TYPE) \
7022+
7023+
#define X(lc, uc) \
7024+
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \
7025+
JS_New##lc##Error(JSContext *ctx, \
7026+
JS_PRINTF_FORMAT const char *fmt, ...) \
7027+
{ \
7028+
JSValue val; \
7029+
va_list ap; \
7030+
\
7031+
va_start(ap, fmt); \
7032+
val = JS_MakeError(ctx, JS_##uc##_ERROR, \
7033+
/*add_backtrace*/true, fmt, ap); \
7034+
va_end(ap); \
7035+
return val; \
7036+
} \
7037+
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \
7038+
JS_Throw##lc##Error(JSContext *ctx, \
7039+
JS_PRINTF_FORMAT const char *fmt, ...) \
7040+
{ \
7041+
JSValue val; \
7042+
va_list ap; \
7043+
\
7044+
va_start(ap, fmt); \
7045+
val = JS_ThrowError(ctx, JS_##uc##_ERROR, fmt, ap); \
7046+
va_end(ap); \
7047+
return val; \
7048+
} \
7049+
7050+
JS_ERROR_MAP(X)
7051+
7052+
#undef X
7053+
#undef JS_ERROR_MAP
70397054

70407055
static int JS_PRINTF_FORMAT_ATTR(3, 4) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, JS_PRINTF_FORMAT const char *fmt, ...)
70417056
{
@@ -7084,39 +7099,6 @@ static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom)
70847099
}
70857100
}
70867101

7087-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7088-
{
7089-
JSValue val;
7090-
va_list ap;
7091-
7092-
va_start(ap, fmt);
7093-
val = JS_ThrowError(ctx, JS_REFERENCE_ERROR, fmt, ap);
7094-
va_end(ap);
7095-
return val;
7096-
}
7097-
7098-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7099-
{
7100-
JSValue val;
7101-
va_list ap;
7102-
7103-
va_start(ap, fmt);
7104-
val = JS_ThrowError(ctx, JS_RANGE_ERROR, fmt, ap);
7105-
va_end(ap);
7106-
return val;
7107-
}
7108-
7109-
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
7110-
{
7111-
JSValue val;
7112-
va_list ap;
7113-
7114-
va_start(ap, fmt);
7115-
val = JS_ThrowError(ctx, JS_INTERNAL_ERROR, fmt, ap);
7116-
va_end(ap);
7117-
return val;
7118-
}
7119-
71207102
JSValue JS_ThrowOutOfMemory(JSContext *ctx)
71217103
{
71227104
JSRuntime *rt = ctx->rt;
@@ -51457,8 +51439,8 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi
5145751439
err = JS_GetException(ctx);
5145851440
is_reject = 1;
5145951441
} else {
51460-
err = JS_MakeError(ctx, JS_TYPE_ERROR, "throw is not a method",
51461-
true);
51442+
err = JS_MakeError2(ctx, JS_TYPE_ERROR, /*add_backtrace*/true,
51443+
"throw is not a method");
5146251444
is_reject = 1;
5146351445
}
5146451446
goto done_resolve;

quickjs.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,12 +756,18 @@ JS_EXTERN void JS_ClearUncatchableError(JSContext *ctx, JSValueConst val);
756756
// JS_Throw(ctx, exc);
757757
JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx);
758758
JS_EXTERN JSValue JS_NewError(JSContext *ctx);
759+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
760+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
761+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
762+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
763+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
764+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
765+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
759766
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
767+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
768+
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
760769
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
761770
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
762-
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
763-
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
764-
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
765771
JS_EXTERN JSValue JS_ThrowOutOfMemory(JSContext *ctx);
766772
JS_EXTERN void JS_FreeValue(JSContext *ctx, JSValue v);
767773
JS_EXTERN void JS_FreeValueRT(JSRuntime *rt, JSValue v);

0 commit comments

Comments
 (0)