jueschus
jueschus

Reputation: 251

"Can't set headers after they are sent" - when setting response directly

I'm using NestJS for my API server and am very satisfied with it. Most of my controller functions are calling async functions and return JSON - works like a charm.

But in some controller functions, i need to set the response/headers/etc directly to the response object, e.g.:

@Get('api/media')
async getMedia(@Param('id') id: string,
               @Req() req) {
    let result = await getMediaFromBackend(id);
    req.res.set('Content-Type', result.contentType); // need to set content-type dynamically
    req.res.send(result.data); // send non-json response
}

In some other case i need to pipe a gzipStream.

It works, but i'm always getting an unhandled rejection in the console:

"Can't set headers after they are sent"

Seems like NestJS wants to set/overwrite Headers after the controller function returns. Any ideas how to avoid this? I would need some functionality to tell NestJS like "im taking full care of the response myself"

Thanks a lot!

Upvotes: 0

Views: 3506

Answers (1)

Kim Kern
Kim Kern

Reputation: 60457

Because you're injecting @Req() and access the response via req.res the standard nest controller behavior is used. If you directly use @Res instead nest won't mess with the response object and you have full control over it.

@Get('api/media')
async getMedia(@Param('id') id: string,
               @Res() res) {
    let result = await getMediaFromBackend(id);
    res.set('Content-Type', result.contentType); // need to set content-type dynamically
    res.send(result.data); // send non-json response
}

Caution! This means interceptors, exception filters etc. won't work for this route.

Upvotes: 2

Related Questions