You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
failAction: detailedError to log, defaultError to response #4229
failAction: 'error'// defaultError to log and to response
failAction: (request,h,err)=>{request.log('error',err);throwerr}// detailedError to log and to response
There is no way to access both detailedError and defaultError in the handler.
For example:
defaultError: Error: Invalid request query input
detailedError: Error [ValidationError]: "foobar" is not allowed
Do you have a new or modified API suggestion to solve the problem?
importJoifrom'joi';// 17.4.0server.route({method: 'GET',path: '/test',options: {validate: {query: Joi.object({foo: Joi.string().required(),}),failAction: 'error',// response: {"statusCode":400,"error":"Bad Request","message":"Invalid request query input"}failAction: 'log',// log to console: Error: Invalid request query inputfailAction(request,h,err){request.log('error',err);throwerr;},// log to console: Error [ValidationError]: "foo" is not allowed to be empty// response: {"statusCode":400,"error":"Bad Request","message":"\"foo\" is not allowed to be empty","validation":{"source":"query","keys":["foo"]}}},},handler(){return'ok';},});
There is no way to response by short error {"statusCode":400,"error":"Bad Request","message":"Invalid request query input"} and log to console detailed error Error [ValidationError]: "foo" is not allowed to be empty.
The other modes seem pretty pointless to me. I think you'd always want the detailed error in the logs and the only thing that really needs configuration is whether to return the detailed error in the response.
I believe this is a valid feature request. Even though you could throw a Boom.badRequest error as Eran mentioned you lose the message generated by Joi for the defaultError. This not a good solution if you have a global failAction setting in your server configuration IMO because there is no way to make an error message that is still a bit precise without providing the full information detailedError has.
We could handle this in a non-breaking way by adding args: [options.details || err, err]here. I'm not a big fan of it because the first arg could be either the detailedError or the defaultError. In the case where we don't have a detailedError both arg would be the same. At least this has the benefit of being a non-breaking change.
If we go that route and don't want to publish a breaking change, I'd suggest we also keep an issue open for the next major version release to replace it with: args: [options.details, err].
Another somewhat related problem is how the default error message includes "request query input", which is useful to know, but the detailed error message doesn't include that source info.
So in my logs, for example, I have to choose between:
Except, option 1 isn't really an option for me, because failAction : 'log' disables enforcement of the validation, which is basically never what I want. Although, I see how it could be useful in some rare cases.
It's also kind of odd how option 1 includes a (relatively useless) stack trace while option 2 does not.
Personally, all of this stuff is my biggest pain point with hapi right now.
I implemented this behavior but it was a bit hacky without having the defaultError in the failAction method.
This implementation is TS and typesafe. That is the reason for some (maybe unnecessary) checks:
import{ValidationError}from"joi";
failAction: (request,_h,err): null=>{if(Boom.isBoom(err)){constvalidation=err.output.payload.validationas|{source?: string}|undefined;constsource=validation?.source??'';if(errinstanceofValidationError){request.log(['validation','error',source],err.message);}throwBoom.badRequest(`Invalid request ${source} input`);}else{// should never be the case, because a failAction is always called with a Boom errorthrowBoom.badRequest('Invalid request input');}}
Activity
mahnunchik commentedon Feb 10, 2021
There is no way to response by short error
{"statusCode":400,"error":"Bad Request","message":"Invalid request query input"}and log to console detailed errorError [ValidationError]: "foo" is not allowed to be empty.sholladay commentedon Feb 13, 2021
Yeah, I always use the last one and I do it at the server level:
The other modes seem pretty pointless to me. I think you'd always want the detailed error in the logs and the only thing that really needs configuration is whether to return the detailed error in the response.
Nargonath commentedon Feb 19, 2021
I believe this is a valid feature request. Even though you could throw a
Boom.badRequesterror as Eran mentioned you lose the message generated by Joi for thedefaultError. This not a good solution if you have a globalfailActionsetting in your server configuration IMO because there is no way to make an error message that is still a bit precise without providing the full informationdetailedErrorhas.We could handle this in a non-breaking way by adding
args: [options.details || err, err]here. I'm not a big fan of it because the first arg could be either thedetailedErroror thedefaultError. In the case where we don't have adetailedErrorboth arg would be the same. At least this has the benefit of being a non-breaking change.If we go that route and don't want to publish a breaking change, I'd suggest we also keep an issue open for the next major version release to replace it with:
args: [options.details, err].In the end the
failActionsignature would be:devinivy commentedon Feb 19, 2021
That's a good thought. Another approach could be to tack the default error onto the detailed error in this case so that it could be accessed:
sholladay commentedon Feb 19, 2021
Another somewhat related problem is how the default error message includes "request query input", which is useful to know, but the detailed error message doesn't include that source info.
So in my logs, for example, I have to choose between:
failAction : 'log':failAction : (request, h, error) => { request.log('error', error); throw error; }:Except, option 1 isn't really an option for me, because
failAction : 'log'disables enforcement of the validation, which is basically never what I want. Although, I see how it could be useful in some rare cases.It's also kind of odd how option 1 includes a (relatively useless) stack trace while option 2 does not.
Personally, all of this stuff is my biggest pain point with hapi right now.
Nargonath commentedon Feb 24, 2021
Good idea @devinivy . I didn't think of this one. Would you consider it a transitional step before a breaking change or the final implementation?
Thanks @sholladay . Interesting stuff to consider as well.
mahnunchik commentedon Feb 24, 2021
I'm really happy that this feature has found followers. I'm looking forward to have it implemented in any from proposed option.
ghdoergeloh commentedon Jan 12, 2022
This is exactly what I was looking for.
I implemented this behavior but it was a bit hacky without having the
defaultErrorin the failAction method.This implementation is TS and typesafe. That is the reason for some (maybe unnecessary) checks:
So in short maybe:
devinivy commentedon Nov 7, 2022
Resolved with v21 #4386