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

Add error context from validator for use in withMessage #1194

Open
kkoster opened this issue Dec 12, 2022 · 4 comments
Open

Add error context from validator for use in withMessage #1194

kkoster opened this issue Dec 12, 2022 · 4 comments

Comments

@kkoster
Copy link

kkoster commented Dec 12, 2022

It would be nice if we could pass custom context associated with a validator (mostly customValidator) to the custom message (withMessage) function. This is especially the case when a customValidator is applying complex rules that cannot be segregated into different validators. For example, within the body of a request I have an array of objects that have identifiers I need to validate against a database. Instead of validating them one at a time, I pass a vector of ids to an endpoint that validates existence an spits back the ids that successfully validated. The difference between what was submitted and what was received gives me the invalid ids. I would like to return the invalid ids in a manner that the withMessage function can pick them up and incorporate them in the message.

Probably the most direct way to do this is to return an object with the ids (or whatever context I want to return) from the validator. An Error object on a synchronous validator or the content of the Promise.reject() on an asynchronous one. The validator framework could then pass that on to the withMessage function as an optional parameter (augmenting the Meta type for the withMessage function). That can then be inspected by the withMessage function for its use.

Without this the validation code must be duplicated in the withMessage function to incorporate useful derived validation information into the message.

@gustavohenke
Copy link
Member

Can you show a sample code of what you're doing/what you'd like express-validator to do?

@kkoster
Copy link
Author

kkoster commented Dec 30, 2022

@gustavohenke for instance, within a validator I may need to access information from a database that has relevance to the error message I want to return. An arbitrary example would be:

.custom(async (dbId) => {
    dbObj = await dbUtility.get(dbId)
    if (dbObj.someProperty !== 'some value') {
        return Promise.reject(dbObj)
    }
})
.withMessage((dbId, { context /* new context object coming from the rejected promise */ }) => ({
        message: `The object ${dbId} has the value of ${context.someProperty} but should have 'some value'}`
    })
)

The withMessage could retrieve the database object all over again and provide the property value, but that puts additional overhead on the validation chain. And, if there are several of these in a chain, it could be come costly. It also begins to violate a principle of clean coding (DRY).

@gustavohenke
Copy link
Member

If your custom validator rejects, the rejected value gets used as the message.
https://express-validator.github.io/docs/custom-error-messages#custom-validator-level

Does that help?

@gustavohenke
Copy link
Member

gustavohenke commented Jan 7, 2023

The withMessage could retrieve the database object all over again

Not really. At the moment withMessage has to be synchronous. It could be implemented, of course.
But for covering cases like yours, it wouldn't be DRY, as you say 😄

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