#Catching HttpExceptions and Node errors separately

3 messages · Page 1 of 1 (latest)

unkempt lynx
#

I want to separate the behaviour for internal Node produced errors (like not enough space) and the HTTP exceptions (mostly produced by the client).

In this case, I want the HTTP exceptions to look like this:

{
  "error": true,
  "messages": [...]
}

And the internal errors like this (the string is always the same):

{
  "error": true,
  "messages": "general.internalServerError"
}
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    const status = exception.getStatus();
    const exceptionBody = exception.getResponse() as any;
    const message = exceptionBody.message || exceptionBody;

    response.status(status).json({
      error: true,
      messages: [message].flat(),
    });
  }
}

@Catch(Error)
export class ErrorExceptionFilter extends BaseExceptionFilter {
  catch(exception: Error, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    const status = HttpStatus.INTERNAL_SERVER_ERROR;
    Logger.error(exception, 'ExceptionsHandler');
    console.error(exception);

    response.status(status).json({
      error: true,
      messages: General.INTERNAL_SERVER_ERROR,
    });
  }
}

However, (in this case the authorization guard) throws an UnauthorizedException but ErrorExceptionFilter catches the error before the HttpExceptionFilter. How can I modify the priority or change the order?

shell hull
#

You bind the filters in the opposite order. If they're bound in the same file, then it's easy. If they're bound in separate modules, then the order is sadly not deterministic.

#

What you could also do is just bind one guard (the genral one) and in the catch, perform an instanceof check on the HttpException (and act accordingly)