hmve

Handle mongoose validation error with custom and localize messages

Usage no npm install needed!

<script type="module">
  import hmve from 'https://cdn.skypack.dev/hmve';
</script>

README

HMVE

Handle mongoose validation error with custom and localize messages

What ?


Mongoose has schema validation, but its error message isn't user-friendly, example :

schema : fullName : { type : String, minlength : 3 }
data   : fullName : 'Bi'

Will generate error message :

Path `fullName` (`Bi`) is shorter than the minimum allowed length (3).

With hmve, you can custom error message, like :

Full name must be at least 3 characters long

and localize :

(Vietnamese) Họ tên phải dài ít nhất 3 kí tự

Config

Let's view simple config file, for :

Use

Add path names

  • For single language, just add $name to mongoose Schema :

      username : { type : String, required : true, unique : true, $name : 'tên tài khoản' },
    

    If $name not specific, hmve will use path ('username')

  • For multi language, use setPathNames() with language package name

    hmve.setPathNames(UserModel, { username : 'tên tài khoản', address : { country : 'quốc gia' } }, 'vi');
    hmve.setPathNames(UserModel, { username : 'ユーザー名'    , address : { country : '国'       } }, 'jpa');
    

Handle error

hmve only handle mongoose validation error, other error type will be return directly.

On mongoose document validate()

Cann't handle unique error.

let user = UserModel({ username : 'boo' });
user.validate(err => {
  err = hmve(UserModel, err);
  if (err) {
      return res.status(400).json({ error : err.message });
    }
  }
});

On mongoose model write method like create(), findOneAndUpdate(), ...

Can handle unique error.

UserModel
  .create({ username : 'boo' })
  .then(user => res.json(user))
  .catch(err => {
    err = hmve(UserModel, err);
    // you can change error code in config()
    if (err.code === 'ERR_MONGOOSE_VALIDATION') { 
      return res.status(400).json({ error : err.message });
    }
    return res.status(500).json({ error : `ERROR DB ${err.message}` });
  });

List error kinds and their context variables

Use this to write custom message templates

KIND CONTEXT VARIABLE
* PATH, PATH_NAME, VALUE
type TYPE, TYPE_NAME, STRING_VALUE
min MIN
max MAX
minlength MIN_LENGTH
maxlength MAX_LENGTH
regexp
enum ENUM_VALUES, STRING_ENUM_VALUES
validate
unique

Error Object

{
   "message"    : "Birthday must be a date, Username is required, Full name must be at least 3 characters long",
   "messages"   : [
     "Birthday must be a date",
     "Username is required",
     "FullName must be at least 3 characters long"
   ],
   "name"       : "ValidationError",
   "code"       : "ERR_MONGOOSE_VALIDATION",
   "model_name" : "Users",
   "pack"       : "DEFAULT",
   "errors"     : [
     {
       "message"      : "Birthday must be a date",
       "context"      : {
         "KIND"         : "type",
         "PATH_NAME"    : "birthday",
         "PATH"         : "birthday",
         "TYPE"         : "Date",
         "TYPE_NAME"    : "date",
         "VALUE"        : "is a date?",
         "STRING_VALUE" : "\"is a date?\""
       },
       "template"     : "{PATH_NAME} must be a {TYPE_NAME}"
     },
     {
       "message"      : "Username is required",
       "context"      : {
         "KIND"         : "required",
         "PATH_NAME"    : "username",
         "PATH"         : "username"
       },
       "template"     : "{PATH_NAME} is required"
     },
     {
       "message"      : "Full name must be at least 3 characters long",
       "context"      : {
         "KIND"         : "minlength",
         "PATH_NAME"    : "full name",
         "PATH"         : "fullName",
         "VALUE"        : "Bi",
         "MIN_LENGTH"   : 3
       },
       "template"     : "{PATH_NAME} must be at least {MIN_LENGTH} characters long"
     }
   ],
}

API LIST

API Description
hmve(model, validationError, [options])

Handle mongoose validation error

validate(doc, [options])

Validate mongoose document, handle error with hmve

setMessageTemplates(messageTemplate, [packageName])

Set message template for a package

setTypeNames(typeNames, [packageName])

Set type names for a package

setPathNames(model, pathNames, [packageName])

Set path names for a package

config(options)

Config

Handler

hmve(model, validationError, [options]) ⇒ Object

Handle only mongoose validation error, other error type will be return directly.

Returns: Object - user-friendly error

Param Type Description
model Object Mongoose model object or name
validationError Object Mongoose validation error
[options] Object options

Options

field Type Description Example
package String Language package name. Default is config.default_package. Must be provide in multi language mode. 'vi', 'jp'
exclude_errors String|Array One or more error kinds will be excluded. Ex: exclude 'required' error when validating update data. 'required', ['required, 'unique']

Example

const hmve = require('hmve');

const UsersSchema = new Schema({
  username : { type : String, required : true                    },
  fullName : { type : String, minlength : 3, $name : 'full name' },
  birthday : { type : Date  ,                                    },
});

const UsersModel = mongoose.model('Users', UsersSchema, 'Users');

let user = UsersModel({
  fullName : 'Bi',
  birthday : 'is a date?',
});

user.validate(err => {
  err = hmve(UsersModel, err);
  if (err) {
     res.status(400).json(err.message); 
     // Birthday must be a date, Username is required, Full name must be at least 3 characters long
  }
});

validate(doc, [options]) ⇒ object

Validate mongoose document, handle error with hmve. This just a convenience syntax with async/await.

Returns: object - user-friendly error

Param Type Description
doc Object mongoose document
[options] Object same as hmve() options

Example

const hmve = require('hmve');

const UsersSchema = new Schema({
  username : { type : String, required : true                    },
  fullName : { type : String, minlength : 3, $name : 'full name' },
  birthday : { type : Date  ,                                    },
});

const UsersModel = mongoose.model('Users', UsersSchema, 'Users');

let user = UsersModel({
  fullName : 'Bi',
  birthday : 'is a date?',
});

let err = await hmve.validate(user);
if (err) {
   res.status(400).json(err.message); 
   // Birthday must be a date, Username is required, Full name must be at least 3 characters long
}

Setter

setMessageTemplates(messageTemplate, [packageName])

Set message template for a package

See: getMessageTemplates('DEFAULT') to view default message template

Param Type Description
messageTemplate Object { <error_kind> : <message_template> }
[packageName] String Package name, ex: 'en', 'vi', 'jp'

Example

hmve.setMessageTemplates({ 
  DEFAULT   : '{PATH_NAME} không hợp lệ',
  type      : '{PATH_NAME} phải là {TYPE_NAME}',
  required  : 'Thiếu thông tin {PATH_NAME}',
  min       : '{PATH_NAME} không được nhỏ hơn {MIN}',
  max       : '{PATH_NAME} không được lớn hơn {MAX}',
  minlength : '{PATH_NAME} dài ít nhất {MIN_LENGTH} kí tự',
  maxlength : '{PATH_NAME} không vượt quá {MAX_LENGTH} kí tự',
  enum      : '{PATH_NAME} phải thuộc một trong các giá trị sau : {STRING_ENUM_VALUES}',
  regex     : '{PATH_NAME} không hợp lệ',
  unique    : '{PATH_NAME} {VALUE} đã được sử dụng, vui lòng chọn {PATH_NAME} khác',
}, 'vi');

setTypeNames(typeNames, [packageName])

Set type names for a package

See: getTypeNames('DEFAULT') to view default type names

Param Type Description
typeNames Object { : <type_name> }
[packageName] String Package name, ex: 'en', 'vi', 'jp'

Example

hmve.setTypeNames({ 
  number  : 'số',
  boolean : 'luận lý',
  date    : 'ngày',
  string  : 'chuỗi',
  array   : 'mảng',
  object  : 'đối tượng',
  buffer  : 'bộ nhớ đệm',
}, 'vi');

setPathNames(model, pathNames, [packageName])

Set path names for a package

Param Type Description
model Object | String mongoose model or model name
pathNames Object { : <path_name> }, which has the same structure as Mongoose Schema
[packageName] String package name, ex: 'en', 'vi'

Example

hmve.setPathNames('User', {
   username : 'tên tài khoản',
   age      : 'tuổi',
   address  : {
     country : 'quốc gia',
     province : 'tỉnh thành'
   }
}, 'vi');

config(options)

set options

Param Type Description
options Object options

Example

hmve.config({
   default_package           : 'DEFAULT',
   msg_delimiter             : ', ',
   path_name_key             : '$name',
   link_to_errors            : 'errors',
   upper_first               : true,
   link_to_origin_error      : false,
   additional_error_fields   : {
     error_name                : 'ValidationError',
     error_code                : 'ERR_MONGOOSE_VALIDATION',
    },
   additional_context_fields : {
     // <context_key> : <schema_key>
   }
});