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.