Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom validation error using Sequelize.js

Is possible to customize the error from the

Sequelize.ValidationError

Model:

  var PaymentType = sequelize.define('payment_type' , {
      id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
      field: 'id'
    },
    code: {
      type: DataTypes.STRING,
      allowNull: false,
      validate:{
        notEmpty: true
      },
      field: 'code'
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      validate:{
        notEmpty: true
      },
      field: 'name'
    }
  }, {
    timestamps: true,
    paranoid: false,
    underscored: true,
    freezeTableName: true,
    tableName: 'payment_types'
  });

My controller:

  update(req, res) {
      paymentType
        .update(req.body, {
          where: {
            id: req.params.id
          }
        })
        .then( updatedRecords => {
          res.status(200).json(updatedRecords);
        })
        .catch(Sequelize.ValidationError, error => {
          res.status(400).json(error);
        })
        .catch( error => {
          res.status(500).json(error);
        });

  },

The errors I get, are this way:

{
  "name": "SequelizeValidationError",
  "message": "Validation error: Validation notEmpty failed",
  "errors": [
    {
      "message": "Validation notEmpty failed",
      "type": "Validation error",
      "path": "name",
      "value": {},
      "__raw": {}
    }
  ]
}

I want to pass the errors like this(only path and message):

{
"name":"The field cannot be empty",
"other_field":"custom error message"
}

I don't know if I can specify a custom message in the model or I have to create a function to build the errors messages.

If I have to build a function, how can I extract the path and customize the message?

Thanks in Advance.

like image 952
joselegit Avatar asked Apr 27 '17 02:04

joselegit


2 Answers

You can specify a custom message for sequelize Validation, Your code will look something like this

`var PaymentType = sequelize.define('payment_type' , {
  id: {
  type: DataTypes.INTEGER(11),
  allowNull: false,
  primaryKey: true,
  autoIncrement: true,
  field: 'id'
},
code: {
  type: DataTypes.STRING,
  allowNull: false,
  validate:{
    notEmpty: {
      args: true,
      msg: “code cannot be empty"
    }
  },
  field: 'code'
},
name: {
  type: DataTypes.STRING,
  allowNull: false,
  validate:{
    notEmpty: {
      args: true,
      msg: “code cannot be empty"
    }
  },
  field: 'name'
}

I specified the validation rule as an object, in the above case, notEmpty should be true so I refactored it to an object setting the args property to true i.e notEmpty should be true, and the second property is msg which contains our custom message

notEmpty: { args: true, msg: “code cannot be empty" }

like image 114
Ayobami Avatar answered Oct 04 '22 11:10

Ayobami


You can catch Sequelize's ValidationError and loop through its ValidationErrorItem's and write a custom message depending on the error type (determined by ValidationErrorItem.validatorKey). Here is a code snippet to get started.

try {
 // sequelize custom logic here
} catch(e) {
    const messages = {};
    if (e instanceof ValidationError) {
        e.errors.forEach((error) => {
            let message;
            switch (error.validatorKey) {
                case 'isEmail':
                    message = 'Please enter a valid email';
                    break;
                case 'isDate':
                    message = 'Please enter a valid date';
                    break;
                case 'len':
                    if (error.validatorArgs[0] === error.validatorArgs[1]) {
                        message = 'Use ' + error.validatorArgs[0] + ' characters';
                    } else {
                        message = 'Use between ' + error.validatorArgs[0] + ' and ' + error.validatorArgs[1] + ' characters';
                    }
                    break;
                case 'min':
                    message = 'Use a number greater or equal to ' + error.validatorArgs[0];
                    break;
                case 'max':
                    message = 'Use a number less or equal to ' + error.validatorArgs[0];
                    break;
                case 'isInt':
                    message = 'Please use an integer number';
                    break;
                case 'is_null':
                    message = 'Please complete this field';
                    break;
                case 'not_unique':
                    message = error.value + ' is taken. Please choose another one';
                    error.path = error.path.replace("_UNIQUE", "");
            }
            messages[error.path] = message;
        });
    }
}
like image 31
netishix Avatar answered Oct 04 '22 09:10

netishix