Repository navigation
feat(fetch): add result-based SafeFetch wrapper [Codex] - #367
jderochervlk wants to merge 6 commits into
Conversation
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Also maybe add some examples that use |
tsnobip
left a comment
There was a problem hiding this comment.
there are a few open questions we should likely settle here before we generalize this kind of helper modules. Please chime in @fhammerschmidt @jderochervlk and anybody who'd like to! :)
| type fetchError = | ||
| | FetchRejected(exn) | ||
| | ResponseNotOk(httpError) |
There was a problem hiding this comment.
I'm wondering if we should not use polymorphic variants here, this way we could more easily compose errors, what do you think @jderochervlk @fhammerschmidt ?
| body: 'body, | ||
| } | ||
|
|
||
| let checkOk = (response: Response.t): result<Response.t, httpError> => |
There was a problem hiding this comment.
nitpicking but LLMs tend to annotate functions a lot, which is not very idiomatic in rescript, this kind of code will likely be taken as a reference at some point, maybe we should remove these type annotations?
| "Request", | ||
| "Response" | ||
| "Response", | ||
| "SafeFetch" |
There was a problem hiding this comment.
should we maybe have the Safe modules as a distinct feature?
Closes #363
Raw Fetch rejects on request failure but fulfills with non-OK HTTP responses, so callers must handle both paths separately. The opt-in
WebAPI.SafeFetchturns request and status failures intoresultvalues and preserves the response and rejection cause.Without SafeFetch:
With SafeFetch:
Safe body readers return the body with its consumed response;
jsonreturnsJSON.t, leaving application-specific validation to the caller.Emitted JavaScript
fetchandfetchWithRequestconstruct their final result directly and call nativefetch. The URL implementation is namedfetchUrland the publicfetchalias is declared after both native calls, avoiding shadowing the browser'sfetchwithout changing the raw bindings.Actual output from the locked ReScript 13.0.0-alpha.5 compiler (URL implementation; body readers and the Request implementation omitted):
A supplied initializer is forwarded, and an absent initializer is omitted. The only runtime import is exception normalization, which preserves the existing
exncontract and original rejection cause.Fetch commonly rejects with a JavaScript Error or DOMException, but
AbortSignal.abort(reason)can supply any JavaScript value.JsExn.fromExceptionretrieves that original value from theexnwrapper. Native Fetch tests cover both the default AbortError and a custom string abort reason.With esbuild 0.28.2 (
bundle: true,minify: true,format: "esm", no gzip), an entry exporting onlyfetchshrinks from 641 to 358 bytes (44%); an entry exporting all SafeFetch helpers shrinks from 1,338 to 1,133 bytes. Both measurements include their bundled runtime dependencies and use the same compiler and bundler settings.Validation: runtime suite (including both fetch entry points, optional initialization, non-OK responses, asynchronous rejection, and synchronous throws), all 27 public feature builds, formatting checks, and documentation build.