interceptors
interceptors copied to clipboard
Fetch interceptor does not abort signal for long response
const http = require('http');
const stream = require('stream');
const { FetchInterceptor } = require('@mswjs/interceptors/fetch');
const interceptor = new FetchInterceptor();
interceptor.apply();
interceptor.on('request', ({ controller}) => {
const readable = new stream.Readable({
read() {
setTimeout(() => this.push('hello'), 100)
}
})
controller.respondWith(new Response(readable))
})
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' })
setInterval(() => res.write('hello\n'), 100)
})
server.listen(3000);
(async () => {
const start = process.hrtime.bigint()
const response = await fetch('http://localhost:3000', {
signal: AbortSignal.timeout(300),
})
console.log((process.hrtime.bigint() - start) / BigInt(1e6));
for await (const data of response.body) {
console.log((process.hrtime.bigint() - start) / BigInt(1e6));
console.log(Buffer.from(data).toString())
}
console.log((process.hrtime.bigint() - start) / BigInt(1e6));
})()
This process continues to run indefinitely. It should abort the request for a long response as well.
P.S. this is weird and somewhat unexpected behavior, I must say.
I think we should extract the signal abort from the handleRequest method and send it to the outer interceptor because each client behaves differently.
From a quick check:
- Fetch abort for the entire request & response. (as shown above)
- ClientRequest does not use this abort at all and relies on Node.js internal code for the abort.
- IIUC,
XMLHttpRequestdoes not have asignalproperty.
WDYT?