Coverage Report

Created: 2026-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/njs/src/njs_error.c
Line
Count
Source
1
2
/*
3
 * Copyright (C) Dmitry Volyntsev
4
 * Copyright (C) NGINX, Inc.
5
 */
6
7
8
#include <njs_main.h>
9
10
11
void
12
njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_t *proto,
13
    u_char *start, size_t size)
14
95.8k
{
15
95.8k
    njs_int_t     ret;
16
95.8k
    njs_value_t   string;
17
95.8k
    njs_object_t  *error;
18
19
95.8k
    ret = njs_string_create(vm, &string, start, size);
20
95.8k
    if (njs_slow_path(ret != NJS_OK)) {
21
0
        return;
22
0
    }
23
24
95.8k
    error = njs_error_alloc(vm, proto, NULL, &string, NULL);
25
95.8k
    if (njs_slow_path(error == NULL)) {
26
0
        return;
27
0
    }
28
29
95.8k
    njs_set_object(dst, error);
30
95.8k
}
31
32
void
33
njs_throw_error_va(njs_vm_t *vm, njs_object_t *proto, const char *fmt,
34
    va_list args)
35
88.9k
{
36
88.9k
    u_char   buf[NJS_MAX_ERROR_STR], *p;
37
38
88.9k
    p = njs_vsprintf(buf, buf + sizeof(buf), fmt, args);
39
40
88.9k
    njs_error_new(vm, &vm->exception, proto, buf, p - buf);
41
88.9k
}
42
43
44
void
45
njs_throw_error(njs_vm_t *vm, njs_object_type_t type, const char *fmt, ...)
46
88.9k
{
47
88.9k
    va_list  args;
48
49
88.9k
    va_start(args, fmt);
50
88.9k
    njs_throw_error_va(vm, njs_vm_proto(vm, type), fmt, args);
51
88.9k
    va_end(args);
52
88.9k
}
53
54
55
void
56
njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
57
    const char *fmt, ...)
58
0
{
59
0
    va_list  args;
60
0
    u_char   buf[NJS_MAX_ERROR_STR], *p;
61
62
0
    va_start(args, fmt);
63
0
    p = njs_vsprintf(buf, buf + sizeof(buf), fmt, args);
64
0
    va_end(args);
65
66
0
    njs_error_new(vm, dst, njs_vm_proto(vm, type), buf, p - buf);
67
0
}
68
69
70
void
71
njs_error_stack_attach(njs_vm_t *vm, njs_value_t value, njs_uint_t skip)
72
74.0k
{
73
74.0k
    size_t               count;
74
74.0k
    uint32_t             line, prev_line;
75
74.0k
    njs_int_t            ret;
76
74.0k
    njs_str_t            name, file, prev_name;
77
74.0k
    njs_chb_t            chain;
78
74.0k
    njs_value_t          *stackval, retval, fobj;
79
74.0k
    njs_vm_code_t        *code;
80
74.0k
    njs_function_t       *function;
81
74.0k
    njs_object_prop_t    *prop;
82
74.0k
    njs_native_frame_t   *frame;
83
74.0k
    njs_flathsh_query_t  fhq;
84
85
74.0k
    if (njs_slow_path(!vm->options.backtrace
86
74.0k
                      || !njs_is_error(&value))
87
74.0k
                      || njs_object(&value)->stack_attached)
88
3.99k
    {
89
3.99k
        return;
90
3.99k
    }
91
92
70.0k
    NJS_CHB_MP_INIT(&chain, vm->mem_pool);
93
94
70.0k
    count = 0;
95
70.0k
    prev_line = 0;
96
70.0k
    prev_name = njs_str_value("");
97
98
201k
    for (frame = vm->top_frame; frame != NULL; frame = frame->previous) {
99
131k
        if (skip != 0) {
100
154
            skip--;
101
154
            continue;
102
154
        }
103
104
131k
        line = 0;
105
131k
        file = njs_str_value("");
106
107
131k
        if (!frame->native) {
108
78.9k
            if (frame->pc == NULL) {
109
0
                continue;
110
0
            }
111
112
78.9k
            code = njs_lookup_code(vm, frame->pc);
113
114
78.9k
            if (code != NULL) {
115
78.9k
                name = code->name;
116
117
78.9k
                if (name.length == 0) {
118
8.93k
                    name = njs_entry_anonymous;
119
8.93k
                }
120
121
78.9k
                line = njs_lookup_line(code->lines, frame->pc - code->start);
122
123
78.9k
                if (!vm->options.quiet) {
124
78.9k
                    file = code->file;
125
78.9k
                }
126
127
78.9k
            } else {
128
0
                name = njs_entry_unknown;
129
0
            }
130
131
78.9k
        } else {
132
52.1k
            function = frame->function;
133
52.1k
            njs_assert(function != NULL);
134
135
52.1k
            if (njs_slow_path(function->bound != NULL)) {
136
0
                continue;
137
0
            }
138
139
52.1k
            name.length = 0;
140
52.1k
            fhq.key_hash = NJS_ATOM_STRING_name;
141
142
52.1k
            ret = njs_flathsh_unique_find(&function->object.hash, &fhq);
143
52.1k
            if (ret == NJS_OK) {
144
51.6k
                prop = fhq.value;
145
146
51.6k
                if (njs_is_string(njs_prop_value(prop))) {
147
51.6k
                    njs_string_get(vm, njs_prop_value(prop), &name);
148
51.6k
                }
149
51.6k
            }
150
151
52.1k
            if (name.length == 0) {
152
504
                njs_set_function(&fobj, function);
153
154
504
                ret = njs_value_property(vm, &fobj, NJS_ATOM_STRING_name,
155
504
                                         &retval);
156
504
                if (ret != NJS_OK) {
157
0
                    continue;
158
0
                }
159
160
504
                if (njs_is_string(&retval)) {
161
504
                    njs_string_get(vm, &retval, &name);
162
163
504
                    if (name.length == 0) {
164
494
                        continue;
165
494
                    }
166
167
504
                } else if (njs_is_symbol(&retval)) {
168
0
                    name = njs_str_value("<symbol>");
169
170
0
                } else {
171
0
                    name = njs_entry_unknown;
172
0
                }
173
504
            }
174
52.1k
        }
175
176
130k
        if (count != 0 && name.start == prev_name.start
177
0
            && line == prev_line)
178
0
        {
179
0
            count++;
180
0
            continue;
181
0
        }
182
183
130k
        if (count > 1) {
184
0
            njs_chb_sprintf(&chain, 64, "      repeats %uz times\n", count);
185
0
        }
186
187
130k
        count = 1;
188
130k
        prev_name = name;
189
130k
        prev_line = line;
190
191
130k
        njs_chb_sprintf(&chain, 10 + name.length, "    at %V ", &name);
192
193
130k
        if (line != 0) {
194
78.9k
            njs_chb_sprintf(&chain, 12 + file.length, "(%V:%uD)\n",
195
78.9k
                            &file, line);
196
78.9k
        } else {
197
51.6k
            njs_chb_append_literal(&chain, "(native)\n");
198
51.6k
        }
199
130k
    }
200
201
70.0k
    if (count > 1) {
202
0
        njs_chb_sprintf(&chain, 64, "      repeats %uz times\n", count);
203
0
    }
204
205
70.0k
    if (njs_chb_size(&chain) == 0) {
206
0
        return;
207
0
    }
208
209
70.0k
    stackval = njs_object_value(&value);
210
211
70.0k
    ret = njs_string_create_chb(vm, stackval, &chain);
212
213
70.0k
    njs_chb_destroy(&chain);
214
215
70.0k
    if (njs_fast_path(ret == NJS_OK)) {
216
70.0k
        njs_object(&value)->stack_attached = 1;
217
70.0k
    }
218
70.0k
}
219
220
221
void
222
njs_error_stack_set(njs_vm_t *vm, njs_value_t *value, njs_str_t *file,
223
    njs_int_t line)
224
6.83k
{
225
6.83k
    njs_chb_t    chain;
226
6.83k
    njs_value_t  *stackval;
227
228
6.83k
    if (njs_slow_path(!vm->options.backtrace
229
6.83k
                      || !njs_is_error(value))
230
6.83k
                      || njs_object(value)->stack_attached)
231
0
    {
232
0
        return;
233
0
    }
234
235
6.83k
    NJS_CHB_MP_INIT(&chain, vm->mem_pool);
236
237
6.83k
    njs_chb_sprintf(&chain, njs_length("    at :\n") + NJS_INT_T_LEN
238
6.83k
                            + file->length,
239
6.83k
                    "    at %V:%uD\n", file, line);
240
241
6.83k
    stackval = njs_object_value(value);
242
243
6.83k
    (void) njs_string_create_chb(vm, stackval, &chain);
244
245
6.83k
    njs_chb_destroy(&chain);
246
6.83k
}
247
248
249
njs_int_t
250
njs_error_stack(njs_vm_t *vm, njs_value_t *value, njs_value_t *stack)
251
154
{
252
154
    njs_int_t  ret;
253
254
154
    ret = njs_value_property(vm, value, NJS_ATOM_STRING_stack, stack);
255
154
    if (njs_slow_path(ret != NJS_OK)) {
256
0
        return ret;
257
0
    }
258
259
154
    if (!njs_is_string(stack)) {
260
0
        return NJS_DECLINED;
261
0
    }
262
263
154
    return NJS_OK;
264
154
}
265
266
267
njs_object_t *
268
njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
269
    const njs_value_t *message, const njs_value_t *errors)
270
95.9k
{
271
95.9k
    njs_int_t            ret;
272
95.9k
    njs_object_t         *error;
273
95.9k
    njs_object_prop_t    *prop;
274
95.9k
    njs_object_value_t   *ov;
275
95.9k
    njs_flathsh_query_t  fhq;
276
277
95.9k
    ov = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_value_t));
278
95.9k
    if (njs_slow_path(ov == NULL)) {
279
0
        goto memory_error;
280
0
    }
281
282
95.9k
    njs_set_undefined(&ov->value);
283
284
95.9k
    error = &ov->object;
285
95.9k
    njs_flathsh_init(&error->hash);
286
95.9k
    njs_flathsh_init(&error->shared_hash);
287
95.9k
    error->type = NJS_OBJECT_VALUE;
288
95.9k
    error->shared = 0;
289
95.9k
    error->extensible = 1;
290
95.9k
    error->fast_array = 0;
291
95.9k
    error->error_data = 1;
292
95.9k
    error->stack_attached = 0;
293
95.9k
    error->__proto__ = proto;
294
95.9k
    error->slots = NULL;
295
296
95.9k
    fhq.replace = 0;
297
95.9k
    fhq.pool = vm->mem_pool;
298
95.9k
    fhq.proto = &njs_object_hash_proto;
299
300
95.9k
    if (name != NULL) {
301
0
        fhq.key_hash = NJS_ATOM_STRING_name;
302
303
0
        ret = njs_flathsh_unique_insert(&error->hash, &fhq);
304
0
        if (njs_slow_path(ret != NJS_OK)) {
305
0
            njs_internal_error(vm, "flathsh insert failed");
306
0
            return NULL;
307
0
        }
308
309
0
        prop = fhq.value;
310
311
0
        prop->type = NJS_PROPERTY;
312
0
        prop->enumerable = 1;
313
0
        prop->configurable = 1;
314
0
        prop->writable = 1;
315
316
0
        prop->u.value = *name;
317
0
    }
318
319
95.9k
    if (message!= NULL) {
320
95.9k
        fhq.key_hash = NJS_ATOM_STRING_message;
321
322
95.9k
        ret = njs_flathsh_unique_insert(&error->hash, &fhq);
323
95.9k
        if (njs_slow_path(ret != NJS_OK)) {
324
0
            njs_internal_error(vm, "flathsh insert failed");
325
0
            return NULL;
326
0
        }
327
328
95.9k
        prop = fhq.value;
329
330
95.9k
        prop->type = NJS_PROPERTY;
331
95.9k
        prop->enumerable = 0;
332
95.9k
        prop->configurable = 1;
333
95.9k
        prop->writable = 1;
334
335
95.9k
        prop->u.value = *message;
336
95.9k
    }
337
338
95.9k
    if (errors != NULL) {
339
0
        fhq.key_hash = NJS_ATOM_STRING_errors;
340
341
0
        ret = njs_flathsh_unique_insert(&error->hash, &fhq);
342
0
        if (njs_slow_path(ret != NJS_OK)) {
343
0
            njs_internal_error(vm, "flathsh insert failed");
344
0
            return NULL;
345
0
        }
346
347
0
        prop = fhq.value;
348
349
0
        prop->type = NJS_PROPERTY;
350
0
        prop->enumerable = 0;
351
0
        prop->configurable = 1;
352
0
        prop->writable = 1;
353
354
0
        prop->u.value = *errors;
355
0
    }
356
357
95.9k
    return error;
358
359
0
memory_error:
360
361
0
    njs_memory_error(vm);
362
363
0
    return NULL;
364
95.9k
}
365
366
367
njs_int_t
368
njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
369
    njs_index_t type, njs_value_t *retval)
370
154
{
371
154
    njs_int_t     ret;
372
154
    njs_value_t   *iterator, *value, list;
373
154
    njs_array_t   *array;
374
154
    njs_object_t  *error;
375
376
154
    if (type != NJS_OBJ_TYPE_AGGREGATE_ERROR) {
377
154
        iterator = NULL;
378
154
        value = njs_arg(args, nargs, 1);
379
380
154
        njs_set_undefined(&list);
381
382
154
    } else {
383
0
        iterator = njs_arg(args, nargs, 1);
384
0
        value = njs_arg(args, nargs, 2);
385
386
0
        if (njs_slow_path(iterator->type < NJS_STRING)) {
387
0
            njs_type_error(vm, "first argument is not iterable");
388
0
            return NJS_ERROR;
389
0
        }
390
391
0
        array = njs_iterator_to_array(vm, iterator, retval);
392
0
        if (njs_slow_path(array == NULL)) {
393
0
            return NJS_ERROR;
394
0
        }
395
396
0
        njs_set_array(&list, array);
397
0
    }
398
399
154
    if (njs_slow_path(!njs_is_string(value))) {
400
154
        if (!njs_is_undefined(value)) {
401
154
            ret = njs_value_to_string(vm, value, value);
402
154
            if (njs_slow_path(ret != NJS_OK)) {
403
0
                return ret;
404
0
            }
405
154
        }
406
154
    }
407
408
154
    error = njs_error_alloc(vm, njs_vm_proto(vm, type), NULL,
409
154
                            njs_is_defined(value) ? value : NULL,
410
154
                            njs_is_defined(&list) ? &list : NULL);
411
154
    if (njs_slow_path(error == NULL)) {
412
0
        return NJS_ERROR;
413
0
    }
414
415
154
    njs_set_object(retval, error);
416
417
154
    njs_error_stack_attach(vm, *retval, 1);
418
419
154
    return NJS_OK;
420
154
}
421
422
423
static const njs_object_prop_init_t  njs_error_constructor_properties[] =
424
{
425
    NJS_DECLARE_PROP_LENGTH(1),
426
427
    NJS_DECLARE_PROP_NAME("Error"),
428
429
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
430
                             0, 0),
431
};
432
433
434
const njs_object_init_t  njs_error_constructor_init = {
435
    njs_error_constructor_properties,
436
    njs_nitems(njs_error_constructor_properties),
437
};
438
439
440
static const njs_object_prop_init_t  njs_eval_error_constructor_properties[] =
441
{
442
    NJS_DECLARE_PROP_LENGTH(1),
443
444
    NJS_DECLARE_PROP_NAME("EvalError"),
445
446
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
447
                             0, 0),
448
};
449
450
451
const njs_object_init_t  njs_eval_error_constructor_init = {
452
    njs_eval_error_constructor_properties,
453
    njs_nitems(njs_eval_error_constructor_properties),
454
};
455
456
457
static const njs_object_prop_init_t  njs_internal_error_constructor_properties[] =
458
{
459
    NJS_DECLARE_PROP_LENGTH(1),
460
461
    NJS_DECLARE_PROP_NAME("InternalError"),
462
463
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
464
                             0, 0),
465
};
466
467
468
const njs_object_init_t  njs_internal_error_constructor_init = {
469
    njs_internal_error_constructor_properties,
470
    njs_nitems(njs_internal_error_constructor_properties),
471
};
472
473
474
static const njs_object_prop_init_t  njs_range_error_constructor_properties[] =
475
{
476
    NJS_DECLARE_PROP_LENGTH(1),
477
478
    NJS_DECLARE_PROP_NAME("RangeError"),
479
480
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
481
                             0, 0),
482
};
483
484
485
const njs_object_init_t  njs_range_error_constructor_init = {
486
    njs_range_error_constructor_properties,
487
    njs_nitems(njs_range_error_constructor_properties),
488
};
489
490
491
static const njs_object_prop_init_t  njs_reference_error_constructor_properties[] =
492
{
493
    NJS_DECLARE_PROP_LENGTH(1),
494
495
    NJS_DECLARE_PROP_NAME("ReferenceError"),
496
497
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
498
                             0, 0),
499
};
500
501
502
const njs_object_init_t  njs_reference_error_constructor_init = {
503
    njs_reference_error_constructor_properties,
504
    njs_nitems(njs_reference_error_constructor_properties),
505
};
506
507
508
static const njs_object_prop_init_t  njs_syntax_error_constructor_properties[] =
509
{
510
    NJS_DECLARE_PROP_LENGTH(1),
511
512
    NJS_DECLARE_PROP_NAME("SyntaxError"),
513
514
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
515
                             0, 0),
516
};
517
518
519
const njs_object_init_t  njs_syntax_error_constructor_init = {
520
    njs_syntax_error_constructor_properties,
521
    njs_nitems(njs_syntax_error_constructor_properties),
522
};
523
524
525
static const njs_object_prop_init_t  njs_type_error_constructor_properties[] =
526
{
527
    NJS_DECLARE_PROP_LENGTH(1),
528
529
    NJS_DECLARE_PROP_NAME("TypeError"),
530
531
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
532
                             0, 0),
533
};
534
535
536
const njs_object_init_t  njs_type_error_constructor_init = {
537
    njs_type_error_constructor_properties,
538
    njs_nitems(njs_type_error_constructor_properties),
539
};
540
541
542
static const njs_object_prop_init_t  njs_uri_error_constructor_properties[] =
543
{
544
    NJS_DECLARE_PROP_LENGTH(1),
545
546
    NJS_DECLARE_PROP_NAME("URIError"),
547
548
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
549
                             0, 0),
550
};
551
552
553
const njs_object_init_t  njs_uri_error_constructor_init = {
554
    njs_uri_error_constructor_properties,
555
    njs_nitems(njs_uri_error_constructor_properties),
556
};
557
558
559
static const njs_object_prop_init_t  njs_aggregate_error_constructor_properties[] =
560
{
561
    NJS_DECLARE_PROP_LENGTH(1),
562
563
    NJS_DECLARE_PROP_NAME("AggregateError"),
564
565
    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
566
                             0, 0),
567
};
568
569
570
const njs_object_init_t  njs_aggregate_error_constructor_init = {
571
    njs_aggregate_error_constructor_properties,
572
    njs_nitems(njs_aggregate_error_constructor_properties),
573
};
574
575
576
void
577
njs_memory_error_set(njs_vm_t *vm, njs_value_t *value)
578
0
{
579
0
    njs_object_t        *object;
580
0
    njs_object_value_t  *ov;
581
582
0
    ov = &vm->memory_error_object;
583
0
    njs_set_data(&ov->value, NULL, NJS_DATA_TAG_ANY);
584
585
0
    object = &ov->object;
586
0
    njs_flathsh_init(&object->hash);
587
0
    njs_flathsh_init(&object->shared_hash);
588
0
    object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_INTERNAL_ERROR);
589
0
    object->slots = NULL;
590
0
    object->type = NJS_OBJECT_VALUE;
591
0
    object->shared = 1;
592
593
    /*
594
     * Marking it nonextensible to differentiate
595
     * it from ordinary internal errors.
596
     */
597
0
    object->extensible = 0;
598
0
    object->fast_array = 0;
599
0
    object->error_data = 1;
600
601
0
    njs_set_object(value, object);
602
0
}
603
604
605
void
606
njs_memory_error(njs_vm_t *vm)
607
0
{
608
0
    njs_memory_error_set(vm, &vm->exception);
609
0
}
610
611
612
static njs_int_t
613
njs_memory_error_constructor(njs_vm_t *vm, njs_value_t *args,
614
    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
615
0
{
616
0
    njs_memory_error_set(vm, retval);
617
618
0
    return NJS_OK;
619
0
}
620
621
622
static njs_int_t
623
njs_memory_error_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
624
    uint32_t unused, njs_value_t *value, njs_value_t *setval,
625
    njs_value_t *retval)
626
0
{
627
0
    int32_t            index;
628
0
    njs_function_t     *function;
629
0
    const njs_value_t  *proto;
630
631
    /* MemoryError has no its own prototype. */
632
633
0
    index = NJS_OBJ_TYPE_INTERNAL_ERROR;
634
635
0
    function = njs_function(value);
636
0
    proto = njs_property_prototype_create(vm, &function->object.hash,
637
0
                                          njs_vm_proto(vm, index));
638
0
    if (proto == NULL) {
639
0
        proto = &njs_value_undefined;
640
0
    }
641
642
0
    *retval = *proto;
643
644
0
    return NJS_OK;
645
0
}
646
647
648
static const njs_object_prop_init_t  njs_memory_error_constructor_properties[] =
649
{
650
    NJS_DECLARE_PROP_LENGTH(1),
651
652
    NJS_DECLARE_PROP_NAME("MemoryError"),
653
654
    NJS_DECLARE_PROP_HANDLER(STRING_prototype,
655
                             njs_memory_error_prototype_create, 0, 0),
656
};
657
658
659
const njs_object_init_t  njs_memory_error_constructor_init = {
660
    njs_memory_error_constructor_properties,
661
    njs_nitems(njs_memory_error_constructor_properties),
662
};
663
664
665
static njs_int_t
666
njs_error_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
667
    njs_index_t unused, njs_value_t *retval)
668
0
{
669
0
    njs_value_assign(retval, njs_argument(args, 0));
670
671
0
    return NJS_OK;
672
0
}
673
674
675
static njs_int_t
676
njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval,
677
    const njs_value_t *error, njs_bool_t want_stack)
678
308
{
679
308
    size_t             length;
680
308
    u_char             *p;
681
308
    njs_int_t          ret;
682
308
    njs_value_t        value1, value2;
683
308
    njs_value_t        *name_value, *message_value;
684
308
    njs_string_prop_t  name, message;
685
686
308
    njs_assert(njs_is_object(error));
687
688
308
    if (want_stack) {
689
154
        ret = njs_error_stack(vm, njs_value_arg(error), retval);
690
154
        if (njs_slow_path(ret == NJS_ERROR)) {
691
0
            return ret;
692
0
        }
693
694
154
        if (ret == NJS_OK) {
695
154
            return NJS_OK;
696
154
        }
697
154
    }
698
699
154
    ret = njs_value_property(vm, (njs_value_t *) error, NJS_ATOM_STRING_name,
700
154
                             &value1);
701
154
    if (njs_slow_path(ret == NJS_ERROR)) {
702
0
        return ret;
703
0
    }
704
705
154
    if (ret == NJS_DECLINED) {
706
0
        njs_atom_to_value(vm, &value1, NJS_ATOM_STRING_Error);
707
0
    }
708
709
154
    name_value = &value1;
710
711
154
    if (njs_slow_path(!njs_is_string(name_value))) {
712
0
        ret = njs_value_to_string(vm, &value1, name_value);
713
0
        if (njs_slow_path(ret != NJS_OK)) {
714
0
            return ret;
715
0
        }
716
0
    }
717
718
154
    (void) njs_string_prop(vm, &name, name_value);
719
720
154
    ret = njs_value_property(vm,  (njs_value_t *) error, NJS_ATOM_STRING_message,
721
154
                             &value2);
722
154
    if (njs_slow_path(ret == NJS_ERROR)) {
723
0
        return ret;
724
0
    }
725
726
154
    if (ret == NJS_DECLINED) {
727
0
        njs_set_empty_string(vm, &value2);
728
0
    }
729
730
154
    message_value = &value2;
731
732
154
    if (njs_slow_path(!njs_is_string(message_value))) {
733
0
        ret = njs_value_to_string(vm, &value2, message_value);
734
0
        if (njs_slow_path(ret != NJS_OK)) {
735
0
            return ret;
736
0
        }
737
738
0
        message_value = &value2;
739
0
    }
740
741
154
    (void) njs_string_prop(vm, &message, message_value);
742
743
154
    if (name.size == 0) {
744
0
        *retval = *message_value;
745
0
        return NJS_OK;
746
0
    }
747
748
154
    if (message.size == 0) {
749
103
        *retval = *name_value;
750
103
        return NJS_OK;
751
103
    }
752
753
51
    if (name.length != 0 && message.length != 0) {
754
51
        length = name.length + message.length + 2;
755
756
51
    } else {
757
0
        length = 0;
758
0
    }
759
760
51
    p = njs_string_alloc(vm, retval, name.size + message.size + 2, length);
761
762
51
    if (njs_fast_path(p != NULL)) {
763
51
        p = njs_cpymem(p, name.start, name.size);
764
51
        *p++ = ':';
765
51
        *p++ = ' ';
766
51
        memcpy(p, message.start, message.size);
767
768
51
        return NJS_OK;
769
51
    }
770
771
0
    njs_memory_error(vm);
772
773
0
    return NJS_ERROR;
774
51
}
775
776
777
static njs_int_t
778
njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
779
    njs_index_t unused, njs_value_t *retval)
780
0
{
781
0
    if (nargs < 1 || !njs_is_object(&args[0])) {
782
0
        njs_type_error(vm, "\"this\" argument is not an object");
783
0
        return NJS_ERROR;
784
0
    }
785
786
0
    return njs_error_to_string2(vm, retval, &args[0], 0);
787
0
}
788
789
790
static njs_int_t
791
njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
792
    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
793
154
{
794
154
    u_char       *p;
795
154
    size_t       length;
796
154
    njs_int_t    ret;
797
154
    njs_str_t    msg, trace;
798
154
    njs_value_t  msg_val, *stackval;
799
800
154
    if (retval != NULL) {
801
154
        if (!njs_is_error(value)) {
802
0
            njs_set_undefined(retval);
803
0
            return NJS_DECLINED;
804
0
        }
805
806
154
        stackval = njs_object_value(value);
807
808
154
        if (setval != NULL) {
809
0
            njs_value_assign(stackval, setval);
810
0
            return NJS_OK;
811
0
        }
812
813
154
        if (!njs_is_string(stackval)) {
814
0
            njs_value_assign(retval, stackval);
815
0
            return NJS_OK;
816
0
        }
817
818
154
        ret = njs_error_to_string2(vm, &msg_val, value, 0);
819
154
        if (njs_slow_path(ret != NJS_OK)) {
820
0
            return ret;
821
0
        }
822
823
154
        njs_string_get(vm, &msg_val, &msg);
824
154
        njs_string_get(vm, stackval, &trace);
825
826
154
        length = msg.length + 1 + trace.length;
827
828
154
        p = njs_string_alloc(vm, retval, msg.length + 1 + trace.length, length);
829
154
        if (njs_slow_path(p == NULL)) {
830
0
            return NJS_ERROR;
831
0
        }
832
833
154
        p = njs_cpymem(p, msg.start, msg.length);
834
154
        *p++ = '\n';
835
154
        memcpy(p, trace.start, trace.length);
836
837
154
        return NJS_OK;
838
154
    }
839
840
    /* Delete. */
841
842
0
    if (njs_is_error(value)) {
843
0
        stackval = njs_object_value(value);
844
0
        njs_set_undefined(stackval);
845
0
    }
846
847
0
    return NJS_OK;
848
154
}
849
850
851
njs_int_t
852
njs_error_to_string(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *error)
853
154
{
854
154
    if (njs_slow_path(!njs_is_object(error))) {
855
0
        njs_type_error(vm, "\"error\" is not an object");
856
0
        return NJS_ERROR;
857
0
    }
858
859
154
    return njs_error_to_string2(vm, retval, error, 1);
860
154
}
861
862
863
static const njs_object_prop_init_t  njs_error_prototype_properties[] =
864
{
865
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
866
                             njs_object_prototype_create_constructor, 0,
867
                             NJS_OBJECT_PROP_VALUE_CW),
868
869
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Error"),
870
                           NJS_OBJECT_PROP_VALUE_CW),
871
872
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
873
                           NJS_OBJECT_PROP_VALUE_CW),
874
875
    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_error_prototype_value_of,
876
                            0, 0),
877
878
    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_error_prototype_to_string,
879
                            0, 0),
880
881
    NJS_DECLARE_PROP_HANDLER(STRING_stack, njs_error_prototype_stack,
882
                             0, NJS_OBJECT_PROP_VALUE_CW),
883
};
884
885
886
const njs_object_init_t  njs_error_prototype_init = {
887
    njs_error_prototype_properties,
888
    njs_nitems(njs_error_prototype_properties),
889
};
890
891
892
const njs_object_type_init_t  njs_error_type_init = {
893
    .constructor = njs_native_ctor(njs_error_constructor, 1,
894
                                   NJS_OBJ_TYPE_ERROR),
895
    .constructor_props = &njs_error_constructor_init,
896
    .prototype_props = &njs_error_prototype_init,
897
    .prototype_value = { .object = { .type = NJS_OBJECT } },
898
};
899
900
901
static const njs_object_prop_init_t  njs_eval_error_prototype_properties[] =
902
{
903
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
904
                             njs_object_prototype_create_constructor, 0,
905
                             NJS_OBJECT_PROP_VALUE_CW),
906
907
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("EvalError"),
908
                           NJS_OBJECT_PROP_VALUE_CW),
909
910
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
911
                           NJS_OBJECT_PROP_VALUE_CW),
912
};
913
914
915
const njs_object_init_t  njs_eval_error_prototype_init = {
916
    njs_eval_error_prototype_properties,
917
    njs_nitems(njs_eval_error_prototype_properties),
918
};
919
920
921
const njs_object_type_init_t  njs_eval_error_type_init = {
922
    .constructor = njs_native_ctor(njs_error_constructor, 1,
923
                                   NJS_OBJ_TYPE_EVAL_ERROR),
924
    .constructor_props = &njs_eval_error_constructor_init,
925
    .prototype_props = &njs_eval_error_prototype_init,
926
    .prototype_value = { .object = { .type = NJS_OBJECT } },
927
};
928
929
930
static njs_int_t
931
njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
932
    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
933
0
{
934
0
    if (nargs >= 1 && njs_is_object(&args[0])) {
935
        /* MemoryError is a nonextensible internal error. */
936
0
        if (!njs_object(&args[0])->extensible) {
937
0
            njs_atom_to_value(vm, retval, NJS_ATOM_STRING_MemoryError);
938
0
            return NJS_OK;
939
0
        }
940
0
    }
941
942
0
    return njs_error_prototype_to_string(vm, args, nargs, unused, retval);
943
0
}
944
945
946
static const njs_object_prop_init_t  njs_internal_error_prototype_properties[] =
947
{
948
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("InternalError"),
949
                           NJS_OBJECT_PROP_VALUE_CW),
950
951
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
952
                           NJS_OBJECT_PROP_VALUE_CW),
953
954
    NJS_DECLARE_PROP_NATIVE(STRING_toString,
955
                            njs_internal_error_prototype_to_string, 0, 0),
956
};
957
958
959
const njs_object_init_t  njs_internal_error_prototype_init = {
960
    njs_internal_error_prototype_properties,
961
    njs_nitems(njs_internal_error_prototype_properties),
962
};
963
964
965
const njs_object_type_init_t  njs_internal_error_type_init = {
966
    .constructor = njs_native_ctor(njs_error_constructor, 1,
967
                                   NJS_OBJ_TYPE_INTERNAL_ERROR),
968
    .constructor_props = &njs_internal_error_constructor_init,
969
    .prototype_props = &njs_internal_error_prototype_init,
970
    .prototype_value = { .object = { .type = NJS_OBJECT } },
971
};
972
973
974
const njs_object_type_init_t  njs_memory_error_type_init = {
975
    .constructor = njs_native_ctor(njs_memory_error_constructor, 1, 0),
976
    .constructor_props = &njs_memory_error_constructor_init,
977
    .prototype_props = &njs_internal_error_prototype_init,
978
    .prototype_value = { .object = { .type = NJS_OBJECT } },
979
};
980
981
982
static const njs_object_prop_init_t  njs_range_error_prototype_properties[] =
983
{
984
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
985
                             njs_object_prototype_create_constructor, 0,
986
                             NJS_OBJECT_PROP_VALUE_CW),
987
988
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("RangeError"),
989
                           NJS_OBJECT_PROP_VALUE_CW),
990
991
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
992
                           NJS_OBJECT_PROP_VALUE_CW),
993
};
994
995
996
const njs_object_init_t  njs_range_error_prototype_init = {
997
    njs_range_error_prototype_properties,
998
    njs_nitems(njs_range_error_prototype_properties),
999
};
1000
1001
1002
const njs_object_type_init_t  njs_range_error_type_init = {
1003
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1004
                                   NJS_OBJ_TYPE_RANGE_ERROR),
1005
    .constructor_props = &njs_range_error_constructor_init,
1006
    .prototype_props = &njs_range_error_prototype_init,
1007
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1008
};
1009
1010
1011
static const njs_object_prop_init_t  njs_reference_error_prototype_properties[] =
1012
{
1013
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
1014
                             njs_object_prototype_create_constructor, 0,
1015
                             NJS_OBJECT_PROP_VALUE_CW),
1016
1017
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("ReferenceError"),
1018
                           NJS_OBJECT_PROP_VALUE_CW),
1019
1020
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
1021
                           NJS_OBJECT_PROP_VALUE_CW),
1022
};
1023
1024
1025
const njs_object_init_t  njs_reference_error_prototype_init = {
1026
    njs_reference_error_prototype_properties,
1027
    njs_nitems(njs_reference_error_prototype_properties),
1028
};
1029
1030
1031
const njs_object_type_init_t  njs_reference_error_type_init = {
1032
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1033
                                   NJS_OBJ_TYPE_REF_ERROR),
1034
    .constructor_props = &njs_reference_error_constructor_init,
1035
    .prototype_props = &njs_reference_error_prototype_init,
1036
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1037
};
1038
1039
1040
static const njs_object_prop_init_t  njs_syntax_error_prototype_properties[] =
1041
{
1042
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
1043
                             njs_object_prototype_create_constructor, 0,
1044
                             NJS_OBJECT_PROP_VALUE_CW),
1045
1046
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("SyntaxError"),
1047
                           NJS_OBJECT_PROP_VALUE_CW),
1048
1049
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
1050
                           NJS_OBJECT_PROP_VALUE_CW),
1051
};
1052
1053
1054
const njs_object_init_t  njs_syntax_error_prototype_init = {
1055
    njs_syntax_error_prototype_properties,
1056
    njs_nitems(njs_syntax_error_prototype_properties),
1057
};
1058
1059
1060
const njs_object_type_init_t  njs_syntax_error_type_init = {
1061
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1062
                                   NJS_OBJ_TYPE_SYNTAX_ERROR),
1063
    .constructor_props = &njs_syntax_error_constructor_init,
1064
    .prototype_props = &njs_syntax_error_prototype_init,
1065
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1066
};
1067
1068
1069
static const njs_object_prop_init_t  njs_type_error_prototype_properties[] =
1070
{
1071
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
1072
                             njs_object_prototype_create_constructor, 0,
1073
                             NJS_OBJECT_PROP_VALUE_CW),
1074
1075
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("TypeError"),
1076
                           NJS_OBJECT_PROP_VALUE_CW),
1077
1078
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
1079
                           NJS_OBJECT_PROP_VALUE_CW),
1080
};
1081
1082
1083
const njs_object_init_t  njs_type_error_prototype_init = {
1084
    njs_type_error_prototype_properties,
1085
    njs_nitems(njs_type_error_prototype_properties),
1086
};
1087
1088
1089
const njs_object_type_init_t  njs_type_error_type_init = {
1090
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1091
                                   NJS_OBJ_TYPE_TYPE_ERROR),
1092
    .constructor_props = &njs_type_error_constructor_init,
1093
    .prototype_props = &njs_type_error_prototype_init,
1094
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1095
};
1096
1097
1098
static const njs_object_prop_init_t  njs_uri_error_prototype_properties[] =
1099
{
1100
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
1101
                             njs_object_prototype_create_constructor, 0,
1102
                             NJS_OBJECT_PROP_VALUE_CW),
1103
1104
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("URIError"),
1105
                           NJS_OBJECT_PROP_VALUE_CW),
1106
1107
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
1108
                           NJS_OBJECT_PROP_VALUE_CW),
1109
};
1110
1111
1112
const njs_object_init_t  njs_uri_error_prototype_init = {
1113
    njs_uri_error_prototype_properties,
1114
    njs_nitems(njs_uri_error_prototype_properties),
1115
};
1116
1117
1118
const njs_object_type_init_t  njs_uri_error_type_init = {
1119
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1120
                                   NJS_OBJ_TYPE_URI_ERROR),
1121
    .constructor_props = &njs_uri_error_constructor_init,
1122
    .prototype_props = &njs_uri_error_prototype_init,
1123
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1124
};
1125
1126
1127
static const njs_object_prop_init_t  njs_aggregate_error_prototype_properties[] =
1128
{
1129
    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
1130
                             njs_object_prototype_create_constructor, 0,
1131
                             NJS_OBJECT_PROP_VALUE_CW),
1132
1133
    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("AggregateError"),
1134
                           NJS_OBJECT_PROP_VALUE_CW),
1135
1136
    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
1137
                           NJS_OBJECT_PROP_VALUE_CW),
1138
};
1139
1140
1141
const njs_object_init_t  njs_aggregate_error_prototype_init = {
1142
    njs_aggregate_error_prototype_properties,
1143
    njs_nitems(njs_aggregate_error_prototype_properties),
1144
};
1145
1146
1147
const njs_object_type_init_t  njs_aggregate_error_type_init = {
1148
    .constructor = njs_native_ctor(njs_error_constructor, 1,
1149
                                   NJS_OBJ_TYPE_AGGREGATE_ERROR),
1150
    .constructor_props = &njs_aggregate_error_constructor_init,
1151
    .prototype_props = &njs_aggregate_error_prototype_init,
1152
    .prototype_value = { .object = { .type = NJS_OBJECT } },
1153
};