AbortController abort reason Parameter
laurenzhonauer opened this issue · comments
Description
In the definition of the AbortController on MDN it is stated, that it is possible to pass a parameter to AbortController.abort()
that is thrown as Error if the AbortController is used in a fetch call.
Current
AbortController.abort()
exists, but does not expect a parameter.
Wanted
Like done in the [@types/mongodb] implementation (see here), the optional reason parameter is also needed in the [@types/node] implementation. And i think before that makes sense, it has to be implemented here in node-fetch
Version
Im using node-fetch as a transitive dependency on version 2.6.6
.
I Set up a project using next.js using ^12.0.7
and ts-node using ^10.4.0
Im not sure if I understood the ecosystem correctly, but i want to point out that i also opened the same issue as discussion for @types/node. I hope thats alright.
As said in the comments on the discussion: I hope i raised this correctly, if not, please help me do it right 😄
Must say that this issue was a bit fussy, didn't exactly understood what you wanted us to do...
that's when i found AbortSignal.reason on MDN.
The signal.reason was added in node v17.2.0
so it's quite new...
Sorry for unclearity. I wasnt aware that its so new, because in the abort documentation they just say, that the parameter exists and I did not see that there is a specific page for AbortSignal.reason.
Yes it seems to be quite new, but it also seems quite handy to me. Thats why I opened the Issue to give the pointer. ^^
You can try and use the following snippet
try{
fetch...
} catch (error) {
if (abortController.signal.aborted) {
return 'http request was timed out';
}
}
You can try and use the following snippet
try{ fetch... } catch (error) { if (abortController.signal.aborted) { return 'http request was timed out'; } }
this approach is incredibly imprecise if the fetch could fail for multiple reasons, or if the AbortSignal could be triggered for different reasons (e.g. timeout vs process shutdown). Unless we can actually use the reason
from the AbortSignal, we risk losing useful information and error context.
So I agree with OP that it would be very valuable to have node-fetch respect the reason
field in the AbortSignal
and change the error message thrown accordingly.
I believe the specifications says that, upon abort, the reason (when given) would be thrown instead of the default AbortError
.
For me this is very invasive. It prevents detecting that an abort has occurred regardless of reason. A middle ground would be to set an error's cause
with the reasen.
try {
const controller = new AbortController();
const timeout = setTimeout(() => { controller.abort("took to long"); }, 1000 * 60);
const response = await fetch("http://takes.very-long-time-to-resepond.com/api", {
signal: contoller.signal,
}).finally(() => clearTimeout(timeout));
/* use response */
} catch (error) {
if (error instanceof AbortError) {
console.log("fetch aborted");
if (error.cause === "took to long") {
console.log("because it took so long");
} else {
throw new Error("Unknown abortion", { cause: error });
}
} else {
throw new Error("Unknown error", { cause: error });
}
}
Alternatively, the AbortError
could carry a reference of the AbortSignal
that triggered the abortion.
But never throw the reason.
Node's implementation of fetch
does throw the given reason
, validating that it is an object otherwise a TypeError
is thrown.