How to Specify a Custom Error Message in Mongoose

Updated: December 30, 2023 By: Guest Contributor Post a comment

Introduction

Mongoose is a powerful ODM library for MongoDB, which provides built-in validation features. However, the default error messages may not always be descriptive enough. Customizing these messages can greatly enhance the experience for end users and developers.

Learning to specify custom error messages in Mongoose can lead to more maintainable and user-friendly validation. This tutorial will guide you through different methods for setting up your error messages in Mongoose schemas.

Custom Error Message in Basic Validation

Start by defining a simple schema. Mongoose allows you to specify validation rules along with custom error messages in the schema definition:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const userSchema = new Schema({
  username: {
    type: String,
    required: [true, 'Username is required. Oops.'s] // Custom error message for the required validator
  }
});

const User = mongoose.model('User', userSchema);

Using Validate Method

The validate method allows more complex validations:

userSchema.path('email').validate({
  validator: function(value) {
    return /\S+@\S+\.\S+/.test(value);
  },
  message: props => `${props.value} is not a valid email address!` // Custom error message using ES6 template strings
});

Custom Error Message in Advanced Validation

For asynchronous validation, use a function that returns a promise. This is useful when your validation involves asynchronous operations, like checking uniqueness against a database:

userSchema.path('username').validate({
  validator: function(value) {
    return User.findOne({ username: value }).then(user => {
      return !user;
    });
  },
  message: 'Username is already taken.' // Custom error message
});

Custom Validators

Create custom validator functions for scenarios not covered by Mongoose’s built-in validators:

function arrayLimit(val) {
  return val.length <= 3;
}

userSchema.path('tags').validate({
  validator: arrayLimit,
  message: 'You can specify up to 3 tags.' // Custom error message
});

Error Handling

After defining the schema validations, you should know how to handle errors. Use try-catch blocks to catch validation errors:

const newUser = new User({ username: 'jdoe', email: 'invalid-email' });
try {
  await newUser.save();
} catch (error) {
  if (error.name === 'ValidationError') {
    for (field in error.errors) {
      console.error(error.errors[field].message); // Log or handle custom error messages
    }
  }
}

Using Middleware

For an advanced setup, Mongoose middleware can help you intercept and modify errors before they reach the application layer:

userSchema.post('save', function(error, doc, next) {
  if (error.name === 'MongoError' && error.code === 11000) {
    next(new Error('There is a duplicate key error.'));
  } else {
    next(error);
  }
});

Conclusion

Custom error messages are an essential feature of application development. Whether through schema definitions or middleware, Mongoose provides a flexible approach to enrich error handling. This leads to improved debugging, better user guidance, and a cleaner codebase.