From a90ae421dda60a1f078950ff1bedf55e1efa299d Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Tue, 22 Mar 2022 17:08:33 +0000 Subject: [PATCH] fix(ext/fetch): Connect async error stack with user code (#13899) --- cli/tests/integration/run_tests.rs | 7 +++++++ cli/tests/testdata/fetch_async_error_stack.ts | 1 + .../testdata/fetch_async_error_stack.ts.out | 5 +++++ ext/fetch/26_fetch.js | 17 +++++++++++++++-- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 cli/tests/testdata/fetch_async_error_stack.ts create mode 100644 cli/tests/testdata/fetch_async_error_stack.ts.out diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index aec17faf01..4411ff0c39 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -2517,3 +2517,10 @@ itest!(wasm_streaming_panic_test { output: "wasm_streaming_panic_test.js.out", exit_code: 1, }); + +// Regression test for https://github.com/denoland/deno/issues/13897. +itest!(fetch_async_error_stack { + args: "run --quiet -A fetch_async_error_stack.ts", + output: "fetch_async_error_stack.ts.out", + exit_code: 1, +}); diff --git a/cli/tests/testdata/fetch_async_error_stack.ts b/cli/tests/testdata/fetch_async_error_stack.ts new file mode 100644 index 0000000000..f583192c2b --- /dev/null +++ b/cli/tests/testdata/fetch_async_error_stack.ts @@ -0,0 +1 @@ +await fetch("https://nonexistent.deno.land/"); diff --git a/cli/tests/testdata/fetch_async_error_stack.ts.out b/cli/tests/testdata/fetch_async_error_stack.ts.out new file mode 100644 index 0000000000..0a7b353e24 --- /dev/null +++ b/cli/tests/testdata/fetch_async_error_stack.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: error sending request for url[WILDCARD] +await fetch("https://nonexistent.deno.land/"); +^[WILDCARD] + at async fetch (deno:[WILDCARD]) + at async file:///[WILDCARD]/fetch_async_error_stack.ts:1:1 diff --git a/ext/fetch/26_fetch.js b/ext/fetch/26_fetch.js index 7118259858..b13552b023 100644 --- a/ext/fetch/26_fetch.js +++ b/ext/fetch/26_fetch.js @@ -409,8 +409,13 @@ * @param {RequestInit} init */ function fetch(input, init = {}) { + // There is an async dispatch later that causes a stack trace disconnect. + // We reconnect it by assigning the result of that dispatch to `opPromise`, + // awaiting `opPromise` in an inner function also named `fetch()` and + // returning the result from that. + let opPromise = undefined; // 1. - return new Promise((resolve, reject) => { + const result = new Promise((resolve, reject) => { const prefix = "Failed to call 'fetch'"; webidl.requiredArguments(arguments.length, 1, { prefix }); // 2. @@ -441,7 +446,7 @@ } // 12. - PromisePrototypeCatch( + opPromise = PromisePrototypeCatch( PromisePrototypeThen( mainFetch(request, false, requestObject.signal), (response) => { @@ -479,6 +484,14 @@ }, ); }); + if (opPromise) { + PromisePrototypeCatch(result, () => {}); + return (async function fetch() { + await opPromise; + return result; + })(); + } + return result; } function abortFetch(request, responseObject, error) {