I want to make an exception filter that extends BaseExceptionFilter, to redirect non-http exceptions to my own logging service.
However, I have to inject my logger service, which means I have to give the filter a constructor:
@Catch()
@Injectable()
export class UncaughtExceptionFilter extends BaseExceptionFilter {
constructor(
private readonly logger: StructuredLogger,
applicationRef: HttpServer,
) {
super(applicationRef);
}
catch(exception: any, host: ArgumentsHost) {
if (exception instanceof HttpException) {
super.catch(exception, host);
} else {
// Have to respond manually to avoid super.catch writing to stderr
this.logger.error(exception, 'uncaught');
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const status = 500;
response.status(status).json({
statusCode: status,
message: 'Internal server error',
});
}
}
}
Because I need to inject, I believe I must provide this class in a module using the APP_FILTER token.
However, BaseExceptionFilter wants an applicationRef argument, and https://stackoverflow.com/a/65473464/3896248 suggests this argument is mandatory. As shown, I've tried having my filter take an HttpServer argument in the hopes that this would be injected - no luck, the injection doesn't seem to provide it. What's the approach here?
I've seen solutions referencing an HTTP_SERVER_REF token -- doesn't seem to work now. I've also seen https://docs.nestjs.com/faq/http-adapter , but when attempting to inject HttpAdapterHost in an in-module as suggested, my application cannot find it to inject.
The docs' injection method works, but you have to make really sure you import HttpAdapterHost from @nestjs/core and not @nestjs/common -- only the one exported from core will inject happily.
(Credit https://stackoverflow.com/a/55483941/3896248 for pointing to the appropriate docs)