Bug Description
onBodySent is not called when using the MockAgent
Reproducible By
import { DecoratorHandler, Dispatcher, fetch, MockAgent } from 'undici';
class LoggingHandler extends DecoratorHandler implements Dispatcher.DispatchHandlers {
private requestBody = '';
constructor(
protected requestOptions: Dispatcher.DispatchOptions,
protected handler: Dispatcher.DispatchHandlers,
) {
super(handler);
}
onConnect(abort: (err?: Error) => void): void {
if (this.handler.onConnect) {
return this.handler.onConnect(abort);
}
}
onBodySent(chunk: any, totalBytesSent: number) {
try {
this.requestBody += Buffer.from(chunk).toString();
} catch (err) {
console.debug('Failed to parse request body:', err);
}
if (this.handler.onBodySent) {
this.handler.onBodySent(chunk, totalBytesSent);
}
}
onComplete(trailers: string[] | null) {
console.log('onComplete', this.requestBody); // In reality this would log to something like GCP with headers/response/status etc
return this.handler.onComplete!(trailers);
}
}
function createLoggingInterceptor() {
return (dispatch: Dispatcher['dispatch']) => {
return function Cache(requestOptions: Dispatcher.DispatchOptions, handler: Dispatcher.DispatchHandlers) {
return dispatch(requestOptions, new LoggingHandler(requestOptions, handler));
};
};
}
describe('onBodySent', () => {
it('onBodySent should be called when using MockAgent', async () => {
const mockAgent = new MockAgent();
mockAgent.disableNetConnect();
const mockPool = mockAgent.get('http://mock.localhost');
const onConnectSpy = jest.spyOn(LoggingHandler.prototype, 'onConnect');
const onBodySentSpy = jest.spyOn(LoggingHandler.prototype, 'onBodySent');
const dispatcher = mockAgent.compose(createLoggingInterceptor());
const bodyString = JSON.stringify({
amount: '100',
});
mockPool
.intercept({
path: '/test',
method: 'POST',
body: () => {
return true;
},
})
.reply(200, {
test: 1,
});
const res = await fetch('http://mock.localhost/test', {
dispatcher,
method: 'POST',
body: bodyString,
});
expect(await res.json()).toEqual({ test: 1 });
expect(onConnectSpy).toHaveBeenCalledTimes(1);
expect(onBodySentSpy).toHaveBeenCalledTimes(1); // fails
});
});
Expected Behavior
onBodySent would be called when making a POST request
Additional context
Looks like it should be called here:
|
handler.onHeaders?.(statusCode, responseHeaders, resume, getStatusText(statusCode)) |
onBodySent future?
Concerned about these future changes which remove onBodySent. Not sure how I'd easily get the request body in an interceptor in the next branch. Mostly creating this issue to figure out what I should be doing instead going forward.
#2723 (comment)
Bug Description
onBodySent is not called when using the MockAgent
Reproducible By
Expected Behavior
onBodySent would be called when making a POST request
Additional context
Looks like it should be called here:
undici/lib/mock/mock-utils.js
Line 317 in a73fd09
onBodySent future?
Concerned about these future changes which remove onBodySent. Not sure how I'd easily get the request body in an interceptor in the next branch. Mostly creating this issue to figure out what I should be doing instead going forward.
#2723 (comment)