Bug report
Package: @hey-api/client-next
Description
In the client generated by @hey-api/client-next, buildUrl(resolvedOpts) is called before the interceptors.request.fns loop. As a result, any request interceptor that mutates opts.baseUrl, opts.url, opts.path, or opts.query is silently ignored when constructing the URL passed to fetch().
The SSE path in the same generated file handles this correctly — it applies request interceptors before building the request URL — creating an asymmetry between the HTTP and SSE code paths.
Generated code (simplified)
// beforeRequest resolves url HERE — before interceptors run
const { opts, url } = await beforeRequest(options);
for (const fn of interceptors.request.fns) {
if (fn) {
await fn(opts); // mutations to opts.baseUrl / opts.url / opts.path / opts.query are ignored
}
}
// url is stale — it was built from pre-interceptor opts
let response = await _fetch(url, requestInit);
Expected behaviour
url should be (re)computed from opts after all request interceptors have finished running, immediately before _fetch(url, requestInit). The order should be:
beforeRequest (merge configs, set auth params, serialize body)
- Run
interceptors.request.fns loop
- Build
url from the (potentially mutated) opts
- Create
requestInit
- Call
_fetch(url, requestInit)
This matches the pattern already used in the SSE path in the same file.
Related
There's a similar (minor) issue in the same generated client: the error interceptor loop passes the original error into every interceptor instead of threading finalError through, so later interceptors never see transformations from earlier ones. Happy to split that out into its own issue if preferred.
Backlinks
Bug report
Package:
@hey-api/client-nextDescription
In the client generated by
@hey-api/client-next,buildUrl(resolvedOpts)is called before theinterceptors.request.fnsloop. As a result, any request interceptor that mutatesopts.baseUrl,opts.url,opts.path, oropts.queryis silently ignored when constructing the URL passed tofetch().The SSE path in the same generated file handles this correctly — it applies request interceptors before building the request URL — creating an asymmetry between the HTTP and SSE code paths.
Generated code (simplified)
Expected behaviour
urlshould be (re)computed fromoptsafter all request interceptors have finished running, immediately before_fetch(url, requestInit). The order should be:beforeRequest(merge configs, set auth params, serialize body)interceptors.request.fnsloopurlfrom the (potentially mutated)optsrequestInit_fetch(url, requestInit)This matches the pattern already used in the SSE path in the same file.
Related
There's a similar (minor) issue in the same generated client: the error interceptor loop passes the original
errorinto every interceptor instead of threadingfinalErrorthrough, so later interceptors never see transformations from earlier ones. Happy to split that out into its own issue if preferred.Backlinks