How to set custom error messages in @hapi/joi?
Asked Answered
H

3

19

I've created following Schema for validation using Joi:

const createProfileSchema = Joi.object().keys({
  username: Joi.string()
    .required()
    .message("username is required")
    .empty()
    .message("username is not allowed to be empty")
    .min(5)
    .message("username must be greater than 5 characters")
    .max(20)
    .message("username must be less than 5 characters")
});

But it throws the flowing error:

 Cannot apply rules to empty ruleset or the last rule added does not support rule properties

      4 |   username: Joi.string()
      5 |     .required()
    > 6 |     .message("username is required")
        |      ^
      7 |     .empty()
      8 |     .message("username is not allowed to be empty")
      9 |     .min(5)

Actually I want to set a custom message for every individual error case.

Hilel answered 16/10, 2019 at 7:53 Comment(1)
Does this answer your question? Node.js + Joi how to display a custom error messages?Bidden
Y
49

You can try something like this with latest version of @hapi/joi package.

const Joi = require("@hapi/joi");

const createProfileSchema = Joi.object().keys({
  username: Joi.string()
    .required()
    .empty()
    .min(5)
    .max(20)
    .messages({
      "string.base": `"username" should be a type of 'text'`,
      "string.empty": `"username" cannot be an empty field`,
      "string.min": `"username" should have a minimum length of {#limit}`,
      "string.max": `"username" should have a maximum length of {#limit}`,
      "any.required": `"username" is a required field`
    })
});

const validationResult = createProfileSchema.validate(
  { username: "" },
  { abortEarly: false }
);

console.log(validationResult.error);

Detailed info can be found in docs:

https://github.com/hapijs/joi/blob/master/API.md#list-of-errors

Young answered 16/10, 2019 at 8:12 Comment(4)
can you please explain why did you pass this { abortEarly: false }Hilel
@ShifutHossain abortEarly options default value is true, and when true it causes to return first error, so if you want to get all errors in your model, it must be set to false, here you have only one field (username) so it does not make difference.Young
and in the docs it says: when true, stops validation on the first error, otherwise returns all the errors found. Defaults to true.Young
What if I want to return a single error message for any cases ?Gruesome
F
5

You can try this

const Joi = require("@hapi/joi"); // as of v16.1.8

const createProfileSchema = Joi.object().keys({
  username: Joi.string()
    .required()
    .empty()
    .min(5)
    .max(20)
    .error(errors=>{ 
     errors.forEach(err=>{  
     switch(err.code){
         case "string.empty":
         err.message='Please insert username'
         break

         case "string.max":
         err.message='username is not allowed to be empty'
         break
        }
      })
    return errors
});
Filagree answered 6/12, 2019 at 15:51 Comment(0)
P
-1

Most of the time you may want to pass custom error message for all cases in current property schema.

Joi.object().keys({
            full_name: Joi.string()
                .required()
                .messages({ "*": "Please enter Full Name" }),
            username: Joi.string().regex(REGEX_USERNAME).required().messages({
                "*": "Please enter Username of {full_name}",
            }),
            email: Joi.string().regex(REGEX_EMAIL).required().messages({
                "*": "Please enter valid email of {full_name}",
            }),
            user_type: Joi.string()
                .valid(...Object.values(USER_TYPE))
                .required()
                .messages({
                    "*": "Please tell User Type of {full_name}",
                }),
        }),

Additional Information
Where full_name in custom error message is a variable where joi will automatically put the value provided for full_name.

Paraphernalia answered 23/7, 2023 at 10:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.