-
Notifications
You must be signed in to change notification settings - Fork 63
Description
When batchMiddleware flushes a queue containing only one request and that request’s fetch rejects (server unavailable, timeout, etc.), the middleware throws RRNLBatchMiddlewareError: Server does not return response for request at index 0. Response should have an array with 1 item(s).
import {
RelayNetworkLayer,
batchMiddleware,
urlMiddleware,
authMiddleware,
retryMiddleware,
} from 'react-relay-network-modern/es'
import { Environment, RecordSource, Store } from 'relay-runtime'
const network = new RelayNetworkLayer([
urlMiddleware({ url: () => Promise.resolve('https://example.com/graphql') }),
batchMiddleware({
batchUrl: () => Promise.resolve('https://example.com/graphql'),
batchTimeout: 15,
}),
authMiddleware({ token: () => Promise.resolve('token') })
])
export const environment = new Environment({
network,
store: new Store(new RecordSource()),
})
For us this causes a problem if the server is down, for example
Root cause
In sendRequests(), the single-request branch awaits next(wrapper.req) without a try/catch:
if (requestList.length === 1) {
const wrapper = requestList[0]
const res = await next(wrapper.req) // <-- rejection bubbles up
wrapper.completeOk(res)
return res
}
Because the rejection isn’t caught, wrapper.done never flips to true, and later finalizeUncompleted() throws the RRNLBatchMiddlewareError.
Expected
The single-request branch should mirror the batched branch: catch the rejection, call wrapper.completeErr(err) (and do the same for duplicates), then rethrow so callers receive the original network error instead of the batch middleware crash.