Skip to content

Commit 080c01f

Browse files
author
Fabrice Bellard
committed
More informative "not a constructor" error message (initial patch by bnoordhuis) (#368)
1 parent c6fe5a9 commit 080c01f

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

quickjs.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7326,6 +7326,22 @@ static JSValue JS_ThrowTypeErrorNotAnObject(JSContext *ctx)
73267326
return JS_ThrowTypeError(ctx, "not an object");
73277327
}
73287328

7329+
static JSValue JS_ThrowTypeErrorNotAConstructor(JSContext *ctx,
7330+
JSValueConst func_obj)
7331+
{
7332+
const char *name;
7333+
if (!JS_IsFunction(ctx, func_obj))
7334+
goto fail;
7335+
name = get_prop_string(ctx, func_obj, JS_ATOM_name);
7336+
if (!name) {
7337+
fail:
7338+
return JS_ThrowTypeError(ctx, "not a constructor");
7339+
}
7340+
JS_ThrowTypeError(ctx, "%s is not a constructor", name);
7341+
JS_FreeCString(ctx, name);
7342+
return JS_EXCEPTION;
7343+
}
7344+
73297345
static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx)
73307346
{
73317347
return JS_ThrowTypeError(ctx, "not a symbol");
@@ -20086,7 +20102,7 @@ static JSValue JS_CallConstructorInternal(JSContext *ctx,
2008620102
goto not_a_function;
2008720103
p = JS_VALUE_GET_OBJ(func_obj);
2008820104
if (unlikely(!p->is_constructor))
20089-
return JS_ThrowTypeError(ctx, "not a constructor");
20105+
return JS_ThrowTypeErrorNotAConstructor(ctx, func_obj);
2009020106
if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) {
2009120107
JSClassCall *call_func;
2009220108
call_func = ctx->rt->class_array[p->class_id].call;
@@ -39947,8 +39963,9 @@ static JSValue JS_SpeciesConstructor(JSContext *ctx, JSValueConst obj,
3994739963
if (JS_IsUndefined(species) || JS_IsNull(species))
3994839964
return JS_DupValue(ctx, defaultConstructor);
3994939965
if (!JS_IsConstructor(ctx, species)) {
39966+
JS_ThrowTypeErrorNotAConstructor(ctx, species);
3995039967
JS_FreeValue(ctx, species);
39951-
return JS_ThrowTypeError(ctx, "not a constructor");
39968+
return JS_EXCEPTION;
3995239969
}
3995339970
return species;
3995439971
}
@@ -48791,7 +48808,7 @@ static JSValue js_reflect_construct(JSContext *ctx, JSValueConst this_val,
4879148808
if (argc > 2) {
4879248809
new_target = argv[2];
4879348810
if (!JS_IsConstructor(ctx, new_target))
48794-
return JS_ThrowTypeError(ctx, "not a constructor");
48811+
return JS_ThrowTypeErrorNotAConstructor(ctx, new_target);
4879548812
} else {
4879648813
new_target = func;
4879748814
}
@@ -49710,7 +49727,7 @@ static JSValue js_proxy_call_constructor(JSContext *ctx, JSValueConst func_obj,
4971049727
if (!s)
4971149728
return JS_EXCEPTION;
4971249729
if (!JS_IsConstructor(ctx, s->target))
49713-
return JS_ThrowTypeError(ctx, "not a constructor");
49730+
return JS_ThrowTypeErrorNotAConstructor(ctx, s->target);
4971449731
if (JS_IsUndefined(method))
4971549732
return JS_CallConstructor2(ctx, s->target, new_target, argc, argv);
4971649733
arg_array = js_create_array(ctx, argc, argv);
@@ -49936,7 +49953,7 @@ static JSValue js_symbol_constructor(JSContext *ctx, JSValueConst new_target,
4993649953
JSString *p;
4993749954

4993849955
if (!JS_IsUndefined(new_target))
49939-
return JS_ThrowTypeError(ctx, "not a constructor");
49956+
return JS_ThrowTypeErrorNotAConstructor(ctx, new_target);
4994049957
if (argc == 0 || JS_IsUndefined(argv[0])) {
4994149958
p = NULL;
4994249959
} else {
@@ -54598,7 +54615,7 @@ static JSValue js_bigint_constructor(JSContext *ctx,
5459854615
int argc, JSValueConst *argv)
5459954616
{
5460054617
if (!JS_IsUndefined(new_target))
54601-
return JS_ThrowTypeError(ctx, "not a constructor");
54618+
return JS_ThrowTypeErrorNotAConstructor(ctx, new_target);
5460254619
return JS_ToBigIntCtorFree(ctx, JS_DupValue(ctx, argv[0]));
5460354620
}
5460454621

tests/test_language.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ function test_delete()
248248
assert(err, true, "delete");
249249
}
250250

251+
function test_constructor()
252+
{
253+
function *G() {}
254+
let ex
255+
try { new G() } catch (ex_) { ex = ex_ }
256+
assert(ex instanceof TypeError)
257+
assert(ex.message, "G is not a constructor")
258+
}
259+
251260
function test_prototype()
252261
{
253262
var f = function f() { };
@@ -660,6 +669,7 @@ test_cvt();
660669
test_eq();
661670
test_inc_dec();
662671
test_op2();
672+
test_constructor();
663673
test_delete();
664674
test_prototype();
665675
test_arguments();

0 commit comments

Comments
 (0)