How to properly lift errors from Joi.alternatives?

Viewed 475

I have a field that can be one of many types. Each type has a different schema. I tried to use Joi.alternatives to validate the request JSON. However, I want to lift the errors from the inner validation functions. Currently alternatives override it with it's error message.

For example, I have a field call customer that can either be a business or a person. If the customer is a person, then only name field is present.

{
  "customer": {
    "name": "John Doe"
  },
  ...
}

On the other hand, if the customer is a business then both name and businessCode fields are present.

{
  "customer": {
    "name": "My Company",
    "businessCode": 1820
  },
  ...
}

I do validation like:

Joi.alternatives()
   .match("one")
   .try(
     Joi.object<Person>({
       name: Joi.string().required()
     }).unknown(false).required(),
     Joi.object<Business>({
       name: Joi.string().required(),
       businessCode: Joi.number().integer().positive().required()
     }).unknown(false).required()
   )

I use match('one') to specify that either business or person should be matched, but not both. When I pass an invalid businessCode like {"businessCode": -999}, Joi throws

"customer" does not match any of the allowed types

which is not as helpful as providing a message like "the business code is negative, which is not allowed as a business". We know that this is a business because a person does not have any business codes. How can I lift the error from the inner validations? One other alternative I thought of is to do validation twice, validate the fields after we validate the field existence, but I'm not sure how to do this within Joi.

1 Answers

This is not possible in joi latest.

In your scenario you say

"the business code is negative, which is not allowed as a business"

but in order to establish this you are implying the matched alternative here is "Business" when in reality (and from joi's PoV) the input has failed the Business schema as much as it failed the Person schema.

For the problem of reporting specific errors when working with alternatives, my solution is to manually run the input thru the different schemas and then create an aggregated response that looks something like "this input failed schema A because this is missing X and failed schema B because it is missing Y"

Related