Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizing global error messages #1179

Open
ChrisGambrell opened this issue Oct 6, 2022 · 3 comments
Open

Customizing global error messages #1179

ChrisGambrell opened this issue Oct 6, 2022 · 3 comments

Comments

@ChrisGambrell
Copy link

ChrisGambrell commented Oct 6, 2022

I love express-validator, but the one thing I miss from Joi is global error messages. In Joi, I could do something like...

const errorMessages = {
    'any.required': 'The field "{#key}" is required.',
    'string.base': 'The field "{#key}" needs to be a string.',
    'string.empty': 'The field "{#key}" cannot be empty.'
}

const schema = Joi.object({
    name: Joi.string().trim().required(),
    dob: Joi.string().optional()
})

const { ... } = schema.messages(errorMessages).validate({ ... })

... and get nice error messages that I could handle globally. When I create my schemas in express-validator and want to use isString(), I have a custom error message for this ValidationChain, but I have to chain the .withMessage({ ... }) with every instance of isString() to use my custom message.

Is there a way to achieve this behavior with express-validator that I am just not aware of/familiar with? Thanks so much in advance.

@ChrisGambrell
Copy link
Author

ChrisGambrell commented Oct 6, 2022

Another option I had thought of was creating my own ValidationChain and using it repeatedly everywhere with the message included, but I wasn't sure how to do that. Something like....

app.post('/foobar', body('foo').isCustomString(), (req: Request, res: Response) => { ... })

Where .isCustomString() is really .isString().withMessage('some dynamic message')

@ChrisGambrell
Copy link
Author

My temporary fix feels ugly and dirty but is as follows...

const exists = (before: ValidationChain): ValidationChain => before.exists().withMessage('This is required').bail()
const isString = (before: ValidationChain): ValidationChain => before.isString().withMessage('Must be a string').bail()
const notEmpty = (before: ValidationChain): ValidationChain => before.notEmpty().withMessage('Cannot be empty').bail()

app.post('/foobar', notEmpty(isString(exists(body('foo'))).trim(), (req: Request, res: Response) => { ... })

I want to do this but chain it instead. Chaining feels much cleaner with express-validator

@gustavohenke
Copy link
Member

Hey @ChrisGambrell, unfortunately what you want is not really possible at the moment.
I'll tag it as an enhancement.

In case you're keen on doing the work, I want to offer a different outlook, as I'm not sure what the API/developer experience for a default message should look like.

I think there's an issue or PR somewhere here asking for the validator name to be included in the error object.

So you could do something like this, leveraging withDefaults:

const customValidationResult = validationResult.withDefaults({
	formatter: error => ({
		...error,
		msg: customErrorMessages[error.validatorName],
	})
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants