Skip to content

Commit 63a2672

Browse files
committed
runtime error track: WIP
1 parent c2b280b commit 63a2672

File tree

5 files changed

+108
-10
lines changed

5 files changed

+108
-10
lines changed

nginx/ngx_http_js_module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,7 @@ ngx_http_js_init_vm(ngx_http_request_t *r, njs_int_t proto_id)
17091709
}
17101710

17111711
ngx_js_ctx_init((ngx_js_ctx_t *) ctx, r->connection->log);
1712+
ctx->conf = (ngx_js_loc_conf_t *) jlcf;
17121713

17131714
ngx_http_set_ctx(r, ctx, ngx_http_js_module);
17141715
}

nginx/ngx_js.c

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,53 @@ ngx_js_inline_map(ngx_js_loc_conf_t *conf, u_char *start, size_t len)
691691
}
692692

693693

694+
static ngx_js_inline_t *
695+
ngx_js_inline_from_stack(ngx_js_loc_conf_t *conf, u_char *start, size_t len)
696+
{
697+
u_char *p, *end;
698+
ngx_uint_t index;
699+
ngx_js_inline_t *inl;
700+
701+
static const u_char prefix[] = "__js_set_";
702+
703+
if (conf == NULL || conf->inlines == NGX_CONF_UNSET_PTR) {
704+
return NULL;
705+
}
706+
707+
end = start + len;
708+
p = start;
709+
710+
while (p + (sizeof(prefix) - 1) <= end) {
711+
if (ngx_strncmp(p, prefix, sizeof(prefix) - 1) == 0) {
712+
p += sizeof(prefix) - 1;
713+
714+
if (p >= end || *p < '0' || *p > '9') {
715+
return NULL;
716+
}
717+
718+
index = 0;
719+
720+
while (p < end && *p >= '0' && *p <= '9') {
721+
index = index * 10 + (*p - '0');
722+
p++;
723+
}
724+
725+
if (index >= conf->inlines->nelts) {
726+
return NULL;
727+
}
728+
729+
inl = conf->inlines->elts;
730+
731+
return &inl[index];
732+
}
733+
734+
p++;
735+
}
736+
737+
return NULL;
738+
}
739+
740+
694741
static ngx_int_t
695742
ngx_engine_njs_compile(ngx_js_loc_conf_t *conf, ngx_log_t *log, u_char *start,
696743
size_t size)
@@ -840,10 +887,12 @@ static ngx_int_t
840887
ngx_engine_njs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname,
841888
njs_opaque_value_t *args, njs_uint_t nargs)
842889
{
843-
njs_vm_t *vm;
844-
njs_int_t ret;
845-
njs_str_t name;
846-
njs_function_t *func;
890+
njs_vm_t *vm;
891+
njs_int_t ret;
892+
njs_str_t name, str;
893+
ngx_str_t s;
894+
ngx_js_inline_t *inl;
895+
njs_function_t *func;
847896

848897
name.start = fname->data;
849898
name.length = fname->len;
@@ -860,7 +909,24 @@ ngx_engine_njs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname,
860909
ret = njs_vm_invoke(vm, func, njs_value_arg(args), nargs,
861910
njs_value_arg(&ctx->retval));
862911
if (ret == NJS_ERROR) {
863-
ngx_js_log_exception(vm, ctx->log, "exception");
912+
if (njs_vm_exception_string(vm, &str) != NJS_OK) {
913+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
914+
"js exception");
915+
return NGX_ERROR;
916+
}
917+
918+
s.data = str.start;
919+
s.len = str.length;
920+
921+
inl = ngx_js_inline_from_stack(ctx->conf, s.data, s.len);
922+
if (inl != NULL) {
923+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
924+
"js exception: %V, included at %s:%ui",
925+
&s, inl->file, inl->line);
926+
} else {
927+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
928+
"js exception: %V", &s);
929+
}
864930

865931
return NGX_ERROR;
866932
}
@@ -1225,9 +1291,11 @@ static ngx_int_t
12251291
ngx_engine_qjs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname,
12261292
njs_opaque_value_t *args, njs_uint_t nargs)
12271293
{
1228-
JSValue fn, val;
1229-
ngx_int_t rc;
1230-
JSContext *cx;
1294+
JSValue fn, val, exc;
1295+
ngx_int_t rc;
1296+
ngx_str_t s;
1297+
JSContext *cx;
1298+
ngx_js_inline_t *inl;
12311299

12321300
cx = ctx->engine->u.qjs.ctx;
12331301

@@ -1243,7 +1311,24 @@ ngx_engine_qjs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname,
12431311
val = JS_Call(cx, fn, JS_UNDEFINED, nargs, &ngx_qjs_arg(args[0]));
12441312
JS_FreeValue(cx, fn);
12451313
if (JS_IsException(val)) {
1246-
ngx_qjs_log_exception(ctx->engine, ctx->log, "call exception");
1314+
exc = JS_GetException(cx);
1315+
1316+
if (ngx_qjs_dump_obj(ctx->engine, exc, &s) == NGX_OK) {
1317+
inl = ngx_js_inline_from_stack(ctx->conf, s.data, s.len);
1318+
if (inl != NULL) {
1319+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
1320+
"js exception: %V, included at %s:%ui",
1321+
&s, inl->file, inl->line);
1322+
} else {
1323+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
1324+
"js exception: %V", &s);
1325+
}
1326+
1327+
} else {
1328+
ngx_log_error(NGX_LOG_ERR, ctx->log, 0, "js exception");
1329+
}
1330+
1331+
JS_FreeValue(cx, exc);
12471332

12481333
return NGX_ERROR;
12491334
}

nginx/ngx_js.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ typedef struct {
185185

186186
#define NGX_JS_COMMON_CTX \
187187
ngx_engine_t *engine; \
188+
ngx_js_loc_conf_t *conf; \
188189
ngx_log_t *log; \
189190
njs_opaque_value_t args[3]; \
190191
njs_opaque_value_t retval; \

nginx/ngx_stream_js_module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,7 @@ ngx_stream_js_init_vm(ngx_stream_session_t *s, njs_int_t proto_id)
12221222
}
12231223

12241224
ngx_js_ctx_init((ngx_js_ctx_t *) ctx, s->connection->log);
1225+
ctx->conf = (ngx_js_loc_conf_t *) jscf;
12251226

12261227
ngx_stream_set_ctx(s, ctx, ngx_stream_js_module);
12271228
}

nginx/t/js_inline.t

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use Test::Nginx;
2424
select STDERR; $| = 1;
2525
select STDOUT; $| = 1;
2626

27-
my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(14);
27+
my $t = Test::Nginx->new()->has(qw/http rewrite/)->plan(15);
2828

2929
use constant TEMPLATE_CONF => <<'EOF';
3030
@@ -46,6 +46,8 @@ http {
4646
js_set $expanded_uri '$uri';
4747
js_set $expanded_complex '$uri.toUpperCase() + "_" + ($arg_a || "none")';
4848
49+
js_set $runtime_bad '(o.a.a)';
50+
4951
%%EXTRA_CONF%%
5052
5153
js_set $test_var test.variable;
@@ -71,6 +73,10 @@ http {
7173
location /expanded {
7274
return 200 "uri=$expanded_uri complex=$expanded_complex";
7375
}
76+
77+
location /runtime_bad {
78+
return 200 "bad=$runtime_bad";
79+
}
7480
}
7581
}
7682
@@ -112,6 +118,10 @@ like(http_get('/expanded'), qr/complex=\/EXPANDED_none/,
112118
like(http_get('/expanded?a=X'), qr/complex=\/EXPANDED_X/,
113119
'expanded $var complex with arg');
114120

121+
http_get('/runtime_bad');
122+
like($t->read_file('error.log'), qr/included at.*nginx\.conf:/s,
123+
'runtime error location');
124+
115125
$t->stop();
116126

117127
###############################################################################

0 commit comments

Comments
 (0)