Skip to content

Commit 9c90163

Browse files
Fetch: making sure catch handler is executed asynchronously.
1 parent 927d38d commit 9c90163

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

nginx/ngx_js_fetch.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -668,13 +668,13 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
668668

669669
fail:
670670

671-
njs_vm_exception_get(vm, njs_value_arg(&lvalue));
672-
673-
ngx_js_fetch_done(fetch, &lvalue, NJS_ERROR);
671+
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, http->log, 0,
672+
"js http done fetch:%p rc:%d", fetch, NJS_ERROR);
674673

675-
njs_value_assign(retval, njs_value_arg(&fetch->promise));
674+
ngx_js_del_event(ngx_external_ctx(vm, njs_vm_external_ptr(vm)),
675+
fetch->event);
676676

677-
return NJS_OK;
677+
return ngx_js_fetch_promissified_result(vm, NULL, NJS_ERROR, retval);
678678
}
679679

680680

nginx/ngx_qjs_fetch.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,14 @@ ngx_qjs_ext_fetch(JSContext *cx, JSValueConst this_val, int argc,
401401

402402
fail:
403403

404-
fetch->response_value = JS_GetException(cx);
404+
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, (&fetch->http)->log, 0,
405+
"js http done fetch:%p rc:%d", fetch, NGX_ERROR);
405406

406-
ngx_qjs_fetch_done(fetch, fetch->response_value, NGX_ERROR);
407+
ngx_js_del_event(ngx_qjs_external_ctx(cx, external), fetch->event);
407408

408-
return promise;
409+
JS_FreeValue(cx, promise);
410+
411+
return qjs_promise_result(cx, JS_EXCEPTION);
409412
}
410413

411414

nginx/t/js_fetch.t

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ http {
6060
js_content test.broken_response;
6161
}
6262
63+
location /broken_catch {
64+
js_content test.broken_catch;
65+
}
66+
6367
location /body {
6468
js_content test.body;
6569
}
@@ -234,6 +238,38 @@ $t->write_file('test.js', <<EOF);
234238
return process_errors(r, tests);
235239
}
236240
241+
function process_errors_catch(r, tests) {
242+
var results = [];
243+
244+
var sync_catch = 'sync';
245+
246+
tests.forEach(args => {
247+
ngx.fetch.apply(r, args)
248+
.then(reply => {
249+
r.return(400, '["unexpected then"]');
250+
})
251+
.catch(e => {
252+
results.push(sync_catch);
253+
254+
if (results.length == tests.length) {
255+
r.return(200, JSON.stringify(results));
256+
}
257+
})
258+
})
259+
260+
sync_catch = 'async';
261+
}
262+
263+
function broken_catch(r) {
264+
var tests = [
265+
['http://127.0.0.1:1/loc'],
266+
['http://127.0.0.1:80800/loc'],
267+
[Symbol.toStringTag],
268+
];
269+
270+
return process_errors_catch(r, tests);
271+
}
272+
237273
function chain(r) {
238274
var results = [];
239275
var reqs = [
@@ -428,15 +464,15 @@ $t->write_file('test.js', <<EOF);
428464
r.return(c, `\${v.request_method}:\${bar}:\${body}`);
429465
}
430466
431-
export default {njs: test_njs, body, broken, broken_response, body_special,
432-
chain, chunked_ok, chunked_fail, header, header_iter,
433-
host_header, multi, loc, property, body_content_length,
434-
user_agent_header };
467+
export default {njs: test_njs, body, broken, broken_response, broken_catch,
468+
body_special,chain, chunked_ok, chunked_fail, header,
469+
header_iter, host_header, multi, loc, property,
470+
body_content_length, user_agent_header };
435471
EOF
436472

437473
$t->try_run('no njs.fetch');
438474

439-
$t->plan(40);
475+
$t->plan(41);
440476

441477
$t->run_daemon(\&http_daemon, port(8082));
442478
$t->waitforsocket('127.0.0.1:' . port(8082));
@@ -495,6 +531,8 @@ is(get_json('/multi'),
495531
like(http_get('/multi?throw=1'), qr/500/s, 'fetch destructor');
496532
like(http_get('/broken'), qr/200/s, 'fetch broken');
497533
like(http_get('/broken_response'), qr/200/s, 'fetch broken response');
534+
like(http_get('/broken_catch'), qr/\["async","async","async"]$/s,
535+
'fetch broken catch');
498536
like(http_get('/chunked_ok'), qr/200/s, 'fetch chunked ok');
499537
like(http_get('/chunked_fail'), qr/200/s, 'fetch chunked fail');
500538
like(http_get('/chain'), qr/200 OK.*SUCCESS$/s, 'fetch chain');

0 commit comments

Comments
 (0)