Search code examples
node.jshapi

data: null in hapi.js preResponse, if Error was thrown


I'm throwing and error like this somewhere in mode code:

throw new Error({
    name: 'notFound',
    message: 'Book not found'
});

And I have a onPreResponse server extension:

server.ext('onPreResponse', async ({ response }, h) => {
    if (isErrorResponse(response)) {
        // So, here the "data" property is null and I can not access name and message
        console.dir(response);
    }
    return h.continue;
});

Because data is null, I can not access my name and message. But if I throw normal object I will have those two properties just fine. Although that would be a hapi error Cannot throw non-error object


Solution

  • Without too much knowledge about the intention of capturing errors by onPreResponse there might be a few things here that can be considered

    https://hapijs.com/api#-requestresponse

    The response object when set. The object can be modified but must not be assigned another object. To replace the response with another from within an extension point, return a new response value. Contains null when no response has been set (e.g. when a request terminates prematurely when the client disconnects).

    So data being null is the expected behaviour so I understand that you want to enrich errors somehow. An error throwed in Hapi is automatically converted to a Boom object now you are trying to throw and Error that is not right constructed, see Error constructor docs first param is an error message not a custom object. Instead you can use a Boom error that the constructor allows you to put custom data in there, e.g.

    throw new Boom('Book not found', { statusCode: 404, decorate: { custom: 'custom' } });
    

    So if you throw that one you should see the following properties

    {
      "data": null,
      "isBoom": true,
      "isServer": false,
      "output": {
        "statusCode": 404,
        "payload": {
          "statusCode": 404,
          "error": "Not Found",
          "message": "Book not found"
        },
        "headers": {}
      },
      "custom": "custom"
    }
    

    You can now add some logging to check if a response is an error ( if(response.isBoom) ) and reading the custom info passed down by your error. Anyway I do think that should be better not to have to use this type of logic within onPreResponse extension, I would try to use common error handling bubbling error from deeper layers to the request handler and returning a proper Boom error from there.