Abortable HTTP Requests: The Detailed Explanation #25
webJose
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I felt that I needed to document how this feature has been implemented in v0.8.0 because it has some decisions that may be worth discussing further, depending on what the majority of users would prefer.
How It Works
As per the specification, aborting a
fetch
call makes its promise to reject. In other words, aborting afetch
call makesfetch
throw. There is no other behavior. This gives us only one choice: To set atry..catch
block up. This is done byDrFetch
, but only ifDrFetch.abortable()
is called.At this point, I must mention the one other detail: Calling
DrFetch.abortable()
changes the value of an internal variable that contains the data-fetching logic. This eliminates the need to have anif
statement at the beginning ofDrFetch.fetch()
to test whether or not we want to detect abortions. In other words, a tiny performance gain.Consequences
The main issue around having the
try..catch
block set up is that it will also trap errors that aren't related to aborting the HTTP request, and as seen in this repository's README, throwing and unwinding the callstack are things we want to avoid due to its performance penalty.Initial Design
My first initial implementation was something like this:
This seems to be the best option in terms of performance: We take full advantage of the
try..catch
block by also returning (instead of throwing) any thrown error, abort error included.The problem comes on the TypeScript side: Without the
failed
property in the response, Intellisense cannot properly present the developer the available options, but with this property, one must code like this:The above is terrible! All this just for TypeScript to be able to narrow the types enough so Intellisense works.
The "other detail" mentioned at the top influences usability: Initially, I thought this should be the new implementation for
DrFetch.fetch()
, but then it affects users that execute non-abortable HTTP requests: Now even if you're not aborting, you're forced to write theif
statement(s) to get Intellisense working.Decisions
In light of the above, the final implementation is a compromise: It catches the error regarding the abortion of the HTTP request, but re-throws the caught error. This causes callstack unwinding once more. The code in the consumer side, however, is very reasonable:
If consumers (developers) would like to account for network errors during the fetching process (DNS failure, physical disconnection, etc.), the call to
DrFetch.fetch()
(or the shortcut functions) will have to be enclosed in atry..catch
block.Also, by making abortable requests an opt-in feature, users that don't require abortable support are not forced to write extra
if
statements.If you would like to weigh in any alternative, please, feel free to do so.
Beta Was this translation helpful? Give feedback.
All reactions