Joi is a powerful JavaScript validation library. You can use it to validate the input you receive to your API, among other uses.
While it comes pretty good error messages out of the box, let’s see some ways to customize them.
You can test any of the examples below using Joi’s playground.
Adding custom labels
Let’s define a schema that accepts a matrix
2D array field.
Joi.object({ matrix: Joi.array().items(Joi.array().items(Joi.number())) })
The following object wouldn’t pass validation because it has a string a
among its elements.
{ matrix: [[0, 1, 2], ['a', 1, 2]] }
By default, Joi returns the following error message:
Validation Error: "matrix[1][0]" must be a number
The error message includes the full path of the invalid value. The top-most key is matrix
. Then, each array element is identified by its array index, starting from 0
.
We can override the default key with label
:
Joi.object({ matrix: Joi.array().items( Joi.array().items(Joi.number().label("matrix value")) ), });
Validation Error: "matrix value" must be a number
We can do the same for any key. Or even specify labels for each array element.
For example, let’s add a label for the elements passed to the matrix
array.
Joi.object({ matrix: Joi.array().items( Joi.array().items(Joi.number()).label("matrix row") ), });
Now, the error message will be::
{ matrix: [[0, 1, 2], 'a'], }
Validation Error: "matrix row" must be an array
Return the key name instead of full path in error messages
Let’s define the following deeply nested schema:
const schema = Joi.object({ a: { b: { c: { d: { e: Joi.number(), }, }, }, }, });
Validating the following object, yields the error message:
const obj = { a: { b: { c: { d: { e: "a", }, }, }, }, };
Validation Error: "a.b.c.d.e" must be a number
See the faulty field is identified with its full path in the object.
We can tweak this behavior by setting the errors.label
option to key
. The default value is path
.
schema.validate(obj, {errors: {label: 'key'}})
Validation error: "e" must be a number
Additionally, we can delete the quotes that wrap the label with the errors.wrap
option:
schema.validate(obj, {errors: {label: 'key', wrap: {label: false}}})
Validation error: e must be a number
See more information about the wrap
and label
options in the any.validate
documentation
To pass custom error messages, we first need to identify the associated error type. For example, a numerical field being less than the specified minimum value is associated to a number.min
error type.
Once we have identified the error type, we can ask Joi to override the predefined error message with the messages
method.
Joi.object({ age: Joi.number() .integer() .min(18) .messages({ "number.min": "You must be at least 18 years old" }), });
See the messages
method accepts an object where each key corresponds to the error type and the value is the desired error message.
With this configuration, the following object will return the error message:
{ age: 1, }
Validation Error: You must be at least 18 years old
You can find the full list of error types in Joi’s documentation.
Referencing the values of other fields in error messages
Let’s include the actual field values in the error message. We can do so with Joi’s templating syntax.
Let’s create a schema that requires both a name
and age
fields.
Joi.object({ name: Joi.string().required(), age: Joi.number() .required() .messages({ "any.required": "You must tells us your age, {name}" }), });
If we don’t set the age
, Joi will return an error message with the value passed to the name
field. See that the field names was wrapped inside {}
.
{ name: "John", }
Validation Error: You must tells us your age, John
You can find more about template syntax in Joi’s documentation.
Referencing fields in deeply nested objects
Let’s modify the schema above by nesting age
inside a data
field.
Joi.object({ name: Joi.string().required(), data: { age: Joi.number() .required() .messages({ "any.required": "You must tells us your age, {name}" }), }, });
Now, let’s pass the following object to validate:
{ name: "John", data: {}, }
We’ll receive a custom error message, but Joi didn’t catch the name
this time.
Validation Error: You must tells us your age,
By default, the key will recognize only siblings of the validated field. In our case, those are all the properties of the data
field. To be more specific we have to use Joi references.
A simple solution in our case is to reference the parent of name
with relative references:
Joi.object({ name: Joi.string().required(), data: { age: Joi.number() .required() .messages({ "any.required": "You must tells us your age, {...name}" }), }, });
See that we’re prepending the field name with three dots: ...name
.
This is s similar to the rules of path resolution in the command line. ..
references the parent field (default behavior), and .
references the current field. We can go higher up the hierarchy by prepending additional dots.
Содержание
- Sidebar
- Search this site
- Categories
- Latest
- Adding custom error messages to Joi js validation
- Adding custom labels
- Return the key name instead of full path in error messages
- Add custom error messages to Joi validation
- Referencing the values of other fields in error messages
- Referencing fields in deeply nested objects
- An easy way to overwrite Joi, Celebrate and Express error messages
- Hapi-Joi error handling with custom messages
- Basic hapi application
- Adding Joi for validation
- Adding the onPreResponse extension point method
- dimitrinicolas/custom-joi-error
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Resources
- License
- Stars
- Watchers
- Forks
- Releases 1
- Packages 0
- Languages
- Footer
- Joi custom error message
- Trouble
- Validator
- Installation
- Usage
- Validate Post
- Validate Get
- Route.all
- More Validation
- Label
- Optional
- Optional and Empty
- Custom Error Messages
- Joi Test Harness
Search this site
Categories
Latest
Adding custom error messages to Joi js validation
Joi is a powerful JavaScript validation library. You can use it to validate the input you receive to your API, among other uses.
While it comes pretty good error messages out of the box, let’s see some ways to customize them.
You can test any of the examples below using Joi’s playground.
Adding custom labels
Let’s define a schema that accepts a matrix 2D array field.
The following object wouldn’t pass validation because it has a string a among its elements.
By default, Joi returns the following error message:
The error message includes the full path of the invalid value. The top-most key is matrix . Then, each array element is identified by its array index, starting from 0 .
We can override the default key with label :
We can do the same for any key. Or even specify labels for each array element.
For example, let’s add a label for the elements passed to the matrix array.
Now, the error message will be::
Return the key name instead of full path in error messages
Let’s define the following deeply nested schema:
Validating the following object, yields the error message:
See the faulty field is identified with its full path in the object.
We can tweak this behavior by setting the errors.label option to key . The default value is path .
Additionally, we can delete the quotes that wrap the label with the errors.wrap option:
See more information about the wrap and label options in the any.validate documentation
Add custom error messages to Joi validation
To pass custom error messages, we first need to identify the associated error type. For example, a numerical field being less than the specified minimum value is associated to a number.min error type.
Once we have identified the error type, we can ask Joi to override the predefined error message with the messages method.
See the messages method accepts an object where each key corresponds to the error type and the value is the desired error message.
With this configuration, the following object will return the error message:
You can find the full list of error types in Joi’s documentation.
Referencing the values of other fields in error messages
Let’s include the actual field values in the error message. We can do so with Joi’s templating syntax.
Let’s create a schema that requires both a name and age fields.
If we don’t set the age , Joi will return an error message with the value passed to the name field. See that the field names was wrapped inside <> .
You can find more about template syntax in Joi’s documentation.
Referencing fields in deeply nested objects
Let’s modify the schema above by nesting age inside a data field.
Now, let’s pass the following object to validate:
We’ll receive a custom error message, but Joi didn’t catch the name this time.
By default, the key will recognize only siblings of the validated field. In our case, those are all the properties of the data field. To be more specific we have to use Joi references.
A simple solution in our case is to reference the parent of name with relative references:
See that we’re prepending the field name with three dots: . name .
This is s similar to the rules of path resolution in the command line. .. references the parent field (default behavior), and . references the current field. We can go higher up the hierarchy by prepending additional dots.
Источник
An easy way to overwrite Joi, Celebrate and Express error messages
Joi is an object schema definition language and validator for JavaScript objects. It is a magical tool that allows you to create a set of rules and validate input data against them. How cool?
Its NPM package boasts of close to 3 Million weekly downloads! Presumably, it is by far the most used JavaScript schema validator, on the planet.
In the personSchema above, name is a required field, but age isn’t. Joi differentiates two by calling required() function on the specific field. It supports many types such as number , boolean , object , binary among others. Their API reference is loaded with this and more information.
What’s more, it’s also possible to define request data that cannot appear together!
Imagine, you have a POST /users/signup endpoint responsible for signing up a user and saving the data to a users collection on MongoDB. With Joi, you can validate the data being sent as part of the request, either on the request body, params or even query ! Watch!
Koa-joi-router from the maintainers of Koa.js comes in handy here.
Express with Joi.
Express also has its own share of glory with celebrate being the Joi middleware of choice.
I believe that was a good introduction to Joi. Onto the business of the day!
Customizing error messages from Joi.
If you send the POST /users/signup above using a REST API client, for instance, Postman, without passing an email , you’re likely to get the following error message from Joi:
“child ”email” fails because [”email” is required]”.
This makes sense to you as the developer, but a typical user might not fathom.
I hope you are able to use knowledge obtained from this tutorial to make your REST API work the way you want it to.
Since GraphQL internally supports schema and its validation, I have purposefully omitted it from the above statement 😀
Источник
Hapi-Joi error handling with custom messages
Recently, I have ventured into the world of nodejs. Coming from XPage development, the learning curve is quite steep. I looked at several back-end frameworks express, feathersjs and Strongloop’s loopback among others. They are all fine frameworks, but the one I fell in love with was hapijs. I really like the concept of “ configuration over code” and the possibility of compartmentalization of the different parts of the application into their own separate niches. hapijs has just been updated to version 17 using async/await coding patterns, which makes most of the tutorials and guides obsolete to some extent.
In order to learn the hapi way, I decided to build a small web application with authentication. I watched Matt Harrison’s latest hapi youtube tutorials and i was hapi. Then I hit a problem with form validation. joi is a really convenient plugin for validation; it provides a JSON object as a validation result after. That’s perfect for developers, but not very user friendly for customers using your website. I googled for a solution and noticed that others also encountered this problem and I did not find a complete explanation to this problem. So I decided to share my solution with others, hopefully you will find it useful. In this post, I’ll try to explain how I came turned the joi JSON object into meaningful error messages for the end-user. Let’s begin with the basic application.
Basic hapi application
Here is the index.js file of the basic application that renders an index page and a login form. I use the Vision plugin to render handlebars templates, and the Inert plugin to server static files, such as the bootstrap 4 style sheet:
Here is the login form:
This results in a simple form:
Adding Joi for validation
After installing joi, it’s ridiculously easy to add validation to the submitted form. Let’s modify the POST login route and add some rules for validation:
You can see that I applied 3 rules, here (line 10–11):
- The username cannot be empty
- The username needs to be a valid email address
- The password cannot be empty.
If I click on the Login button with this modification, Joi throws back a general JSON error:
No matter how many rules are broken, the message is always the same canned “Invalid request payload input”. I would like to have a detailed error message for all 3 rules, so that I can inform my end user how to fix the errors. Even though, I enabled the abortEarly: false option (line 7), I only get this general message.
Luckily, there’s a solution, using the failAction:(request, h, err) => <> option. Let’s see how the POST route looks like with failAction implemented (line 13–16):
If I check my JSON joi error object now, you can see that there are detailed messages of all errors and even a validation object:
Now this is more like it, the detailed JSON object contains enough information to give detailed feedback to the end user. However, we don’t want to show raw JSON to the user; I would like to re-render the login page with easily understandable error messages. In order to achieve that, we need to intercept the error object before it reaches the user using a hapijs lifecycle function.
Adding the onPreResponse extension point method
We need to check if the response is a Boom object. All joi generated errors use the standard Boom library, if the response is not a Boom object , we can return the response without interfering (line 4–6).
This extension point will handle not only login errors, but errors coming from other parts of the application, as well. Thus, the login errors are handled only if the response comes from the /login url and used the post method (line 8).
The request.response.details contains the detailed error messages. Using these messages, the developer needs to create the business logic to render the user friendly messages and supply this logic via an error object to the login handlebars template.
I implemented the logic by checking for the presence of the actual error messages (line 2, 10, 19) and sending an error object with boolean variables to the handlebars template. The user eventually sees these error messages:
The complete code is available at github repo: hapi-joi-error repo. Let me know if the explanation is not clear.
Источник
dimitrinicolas/custom-joi-error
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
custom-joi-error
Customize Joi errors, by stripping quotes and setting key specific error language.
Call customJoiError function with Joi’s validation result as first arguments.
You can pass options as second argument.
- stripQuotes (default: true ) Remove quote from key label in error message.
- language (default: <> ) Set key specific error message, example :
See Joi language file for full messages list.
This project is licensed under the MIT license.
About
Customize Joi errors, by stripping quotes and setting key specific error language.
Resources
License
Stars
Watchers
Forks
Releases 1
Packages 0
Languages
© 2023 GitHub, Inc.
You can’t perform that action at this time.
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.
Источник
Joi custom error message
by John Vincent
Posted on July 4, 2017
Object schema description language and validator for JavaScript objects.
This stuff ends up sprayed everywhere, so let’s create a reference document.
Trouble
This package is close but has problems with handling errors. Thus I rolled my own based on it.
Notes for when the issues are resolved
Validator
Installation
Usage
Define a schema
Set some options
Validate Post
Validate Get
Route.all
The router.route() API makes this possible.
This is the final implementation. This worked.
The signature of .all
the following was actually passed
validator.body is actually
or, it is a function that
- accepts (schema, opts)
- returns function jvfunc2 (req, res, next)
That is how to ‘inject my own function’ and still satisfy the requires of the calling function.
More Validation
Label
Always use .label, for example
The text in .label() will be used in the error message.
Optional
Field is optional but not empty.
Optional and Empty
Field is optional and could be empty. X-editable passes extra empty parameters.
Custom Error Messages
This revolves around the idea of overriding Joi’s own messages.
See node_modules/joi/language.js , which will look something like
The key is to understand which property you seek to override.
will override language: string: email.
In practice it can take a little playing around to figure which language property to override.
shows the basic idea.
Joi Test Harness
Use this as a starter
An easy way to thoroughly test validations before putting them into real code.
Источник
Methmi
Posted on Sep 23, 2022
• Originally published at Medium
Validation is a crucial step. But one look at the lines of IFs spawning from endless checks could send us over to NPM, hoping to find the perfect library.
And one of the validation libraries you would find is Joi. And like its name, it’s a joy to use.
With Joi, you can
Describe your data using a simple, intuitive and readable language.
So to ensure some user input contains a name and a valid email, it’s simply
const schema = Joi.object({
name: Joi.string()
.min(3)
.max(30)
.required(),
email: Joi.string()
.email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
Enter fullscreen mode
Exit fullscreen mode
This code block validates an input to have a name
property with a number of characters between 3 and 30, and an email
with two domain parts (sample.com) and a top level domain (TLD) of either .com or .net.
But to get a better view of what Joi has to offer, let’s see how we could build a simple form that validates a user’s input according to a schema.
A Simple Form Validation
Installing Joi is as easy as running:
npm i joi
Enter fullscreen mode
Exit fullscreen mode
After importing Joi at the top of your file with,
const Joi = require("joi");
Enter fullscreen mode
Exit fullscreen mode
Joi can be used by first constructing a schema, then validating a value against the constructed schema.
For this example let’s assume that we already have four text fields taking in a user’s name and email and asks to enter a password twice.
Now to create the schema that Joi will validate against. Since a schema is designed to resemble the object we expect as an input, the schema for our four property form data object will look like this:
const objectSchema = {
name: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email({
minDomainSegments: 2,
tlds: { allow: ["com", "net"] },
}),
password: Joi.string()
.pattern(new RegExp("^[a-zA-Z0-9]{3,30}$"))
.required()
.messages({
"string.pattern.base": `Password should be between 3 to 30 characters and contain letters or numbers only`,
"string.empty": `Password cannot be empty`,
"any.required": `Password is required`,
}),
repeatPassword: Joi.valid(userData.password).messages({
"any.only": "The two passwords do not match",
"any.required": "Please re-enter the password",
}),
};
Enter fullscreen mode
Exit fullscreen mode
According to this schema:
-
name
is validated to be:- an alphanumeric string
- between 3 to 30 characters
- a required field
-
email
is checked to have :- two domain parts (sample.com)
- a top level domain (TLD) of either .com or .net
Custom Error Messages
The fields name
and email
use default error messages:
But the fields password
and repeatPassword
use .messages()
to return a custom error message for a set of specific error types.
For example, the custom error messages for the password
field are:
.messages({
“string.pattern.base”: `Password should be between 3 to 30 characters and contain letters or numbers only`,
“string.empty”: `Password cannot be empty`,
“any.required”: `Password is required`,
}),
Enter fullscreen mode
Exit fullscreen mode
The first one is a custom message for an error of type string.pattern.base
, if the entered value does not match the RegExp string (since the password
field is validated with a RegExp).
Likewise, if a an error of type string.empty
is returned (the field is left blank) the custom error message “Password cannot be empty” is shown instead of the default.
Moving on to repeatPassword
, Joi.valid()
makes sure that the only valid value allowed for the repeatPassword
field is whatever the user data is for the password
field. The custom error message shown for an any.only
error type is shown when the entered value does not match the provided allowed value, which is userData.password
in this case.
The full list of possible errors in Joi can be viewed here:
https://github.com/hapijs/joi/blob/master/API.md#list-of-errors
Validating the Form Field on an onChange event
In this example, each form field will have its own error message. So to make updating the state of each error message cleaner, an object was created to hold the values of error messages for all form fields with a useReducer hook to manage its state.
//INITIAL VALUE OF ALL ERROR MESSAGES IN THE FORM
//Each property denotes an error message for each form field
const initialFormErrorState = {
nameError: “”,
emailError: “”,
pwdError: “”,
rpwdError: “”,
};
const reducer = (state, action) => {
return {
…state,
[action.name]: action.value,
};
};
const [state, dispatch] = useReducer(reducer,initialFormErrorState);
Enter fullscreen mode
Exit fullscreen mode
The reducer
function returns an updated state object according to the action passed in, in this case the name of the error message passed in.
For a detailed explanation on the useReducer hook with an example to try out, feel free to check out my article on using the useReducer hook in forms.
Moving on to handling the onChange events of the form fields, a function can be created to take in the entered value and the name of the error message property that should show the error message (to be used by the dispatch
function of the useReducer hook).
const handleChange = (e, errorFieldName) => {
setUserData((currentData) => {
return {
...currentData,
[e.target.id]: e.target.value,
};
});
const propertySchema = Joi.object({
[e.target.id]: objectSchema[e.target.id],
});
const result = propertySchema.validate({ [e.target.id]: e.target.value });
result.error == null
? dispatch({
name: errorFieldName,
value: "",
})
: dispatch({
name: errorFieldName,
value: result.error.details[0].message,
});
};
Enter fullscreen mode
Exit fullscreen mode
Line 2 to line 7 updates the state of the userData
object with the form field’s input. For simplicity, each form form field’s id is named its corresponding property on the userData
object.
propertySchema
on line 8 is the object that holds the schema of the form field that’s calling the handleChange
function. The object objectSchema
contained properties that were named after each form fields id, therefore, to call a fields respective schema and to convert it into a Joi object, Joi.object({[e.target.id] :objectSchema[e.target.id],})
is used and the resulting schema object is stored in propertySchema
.
Next, the input data is converted to an object and validated against the schema in propertySchema
with .validate()
.
This returns an object with a property called error
, this property contains useful values like the error type (useful when creating custom messages) and the error message.
But, if the error
property is not present in result
, a validation error has not occurred, which is what we are checking in line 13.
If a error
is present, the dispatch function is invoked with the name of the form error object’s field that should be updated in name
, and the error message that it should be updated to in value
.
This will make more sense when we look at how handleChange
is called in a form field. Given below is how the form field ‘Name’ calls handleChange
.
<TextField
//TextField component properties
...
onChange={(value) => handleChange(value, “nameError”)}
value={userData.name}
/>
Enter fullscreen mode
Exit fullscreen mode
handleChange
accepts the value of the field as the first parameter and then the name of the respective error object’s field that the dispatch
function in handleChange
is supposed to update, nameError
.
The object, initialFormErrorState
had one property for each form field’s error message. In this case, any validation error in the ‘Name’ field will change the nameError
property of initialFormErrorState
which will in turn be displayed in the respective alert box under the form field.
Here’s a look at the finished form:
Hope this simple example helped show how joyful validation with Joi can be. 😊
Till next time, happy coding!
Happy emoji vector created by freepik — www.freepik.com
Extending on Ashish Kadam’s answer, if you have many different error types, you can check which type of error is present, and set its message accordingly:
Joi v17.4.0
v17.4.0 uses err.code
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().error(errors => {
errors.forEach(err => {
switch (err.code) {
case "any.empty":
err.message = "Value should not be empty!";
break;
case "string.min":
err.message = `Value should have at least ${err.local.limit} characters!`;
break;
case "string.max":
err.message = `Value should have at most ${err.local.limit} characters!`;
break;
default:
break;
}
});
return errors;
}),
// ...
});
You can check the list of errors here: Joi 17.4.0 API Reference > Errors > List of errors
Joi v14.3.1
v14.3.1 uses err.type
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().error(errors => {
errors.forEach(err => {
switch (err.type) {
case "any.empty":
err.message = "Value should not be empty!";
break;
case "string.min":
err.message = `Value should have at least ${err.context.limit} characters!`;
break;
case "string.max":
err.message = `Value should have at most ${err.context.limit} characters!`;
break;
default:
break;
}
});
return errors;
}),
// ...
});
You can check the list of errors here: Joi 14.3.1 API Reference > Errors > List of errors
Also you can check the any.error
reference for more information. Quoting the docs:
Overrides the default joi error with a custom error if the rule fails where:
err
can be:
- an instance of
Error
— the override error.- a
function(errors)
, taking an array of errors as argument, where it must either:
- return a
string
— substitutes the error message with this text- return a single
object
or anArray
of it, where:
type
— optional parameter providing the type of the error (eg.number.min
).message
— optional parameter iftemplate
is provided, containing the text of the error.template
— optional parameter ifmessage
is provided, containing a template string, using the same format as usual joi language errors.context
— optional parameter, to provide context to your error if you are using thetemplate
.- return an
Error
— same as when you directly provide anError
, but you can customize the error message based on the errors.options
:
self
— Boolean value indicating whether the error handler should be used for all errors or only for errors occurring on this property (true
value). This concept only makes sense forarray
orobject
schemas as other values don’t have children. Defaults tofalse
.
Original answer:
The current way (I personally find it better) is to use .messages()
(or .prefs({messages})
).
const Joi = require('@hapi/joi');
const joiSchema = Joi.object({
a: Joi.string()
.min(2)
.max(10)
.required()
.messages({
'string.base': `"a" should be a type of 'text'`,
'string.empty': `"a" cannot be an empty field`,
'string.min': `"a" should have a minimum length of {#limit}`,
'any.required': `"a" is a required field`
})
});
const validationResult = joiSchema.validate({ a: 2 }, { abortEarly: false });
console.log(validationResult.error); // expecting ValidationError: "a" should be a type of 'text'
Usage of .errors()
is not recommended just to update default message with custom message.
.prefs({ messages })
is an elaborate way to provide more options as preferences. The other options for prefs are taken directly from options of .validate()
Further read: https://github.com/hapijs/joi/issues/2158
Update 1: I saw that the above explanation did not work out for some folks, so I have put up some code to test yourself. Check it here: https://runkit.com/embed/fnfaq3j0z9l2
Also updated the code snippet shared previously to have details from package inclusion, to usage, to calling the actual validation method.
Update 2: The list of joi error types and their description (for .messages()
— like string.base, array.unique, date.min etc..) is available here.
Update 3: Joi has moved from hapi project to standalone: https://www.npmjs.com/package/joi.
Make sure you are using latest version (or at least above v17).
Joi Version 14.0.0
const SchemaValidation = {
coins: Joi.number()
.required()
.error(() => {
return {
message: 'Coins is required.',
};
}),
challenge_name: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge name is required.',
};
}),
challengeType: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge type is required.',
};
}),
challengeDescription: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge description is required.',
};
}),
};
In errors object you can get, error type and change message according.