Как отобразить сообщения об ошибках проверки последовательности в Express API

#javascript #node.js #express #orm #sequelize.js

#javascript #node.js #экспресс #orm #sequelize.js

Вопрос:

У меня есть эта модель организации, используемая в Node.js / Express API с Sequelize ORM под управлением MySQL. Когда я нарушаю правило 2-100 символов в соответствии с validation в первом примере кода ниже, я получаю классический err элемент из блока catch во втором примере кода, который не содержит никакой информации об ошибке проверки.

Я хотел бы вместо этого отобразить сообщение об ошибке проверки, которое вы можете увидеть под validation { len: { msg: ...}} в модели. По крайней мере, консоль.запишите это, а затем позже отобразите конечному пользователю.

Однако руководство по проверке последовательности и любая другая информация, которую я могу найти, не объясняют, как я использую это пользовательское сообщение об ошибке. Итак, мой вопрос в том, как я могу использовать его и отобразить.

Модель:

 'use strict'

const { Sequelize, DataTypes } = require('sequelize');
const db = require('./../config/db.js')

const Organization = db.define('organizations', {
  id: {
    type: DataTypes.UUID,
    defaultValue: Sequelize.UUIDV4,
    primaryKey: true,
    allowNull: false,
    unique: true,
    validate: {
      isUUID: {
        args: 4,
        msg: 'The ID must be a UUID4 string'
      }
    }
  },
  name: {
    type: DataTypes.STRING,
    required: true,
    allowNull: false,
    validate: {
      len: {
        args: [2, 100],
        msg: 'The name must contain between 2 and 100 characters.' // Error message I want to display
      }
    }
  },
  created_at: {
    type: DataTypes.DATE,
    required: true,
    allowNull: false
  },
  updated_at: {
    type: DataTypes.DATE,
    required: true,
    allowNull: false
  },
  deleted_at: {
    type: DataTypes.DATE
  }
},
{
  underscored: true,
  paranoid: true,
  tableName: 'organizations',
  updatedAt: 'updated_at',
  createdAt: 'created_at',
  deletedAt: 'deleted_at'
})

module.exports = Organization
  

Контроллер:

 /**
 *  @description Create new organization
 *  @route POST /api/v1/organizations
 */

exports.createOrganization = async (req, res, next) => {
  try {
    const org = await Organization.create(
      req.body,
      {
        fields: ['name', 'type']
      })
    return res.status(200).json({
      success: true,
      data: {
        id: org.id,
        name: org.name
      },
      msg: `${org.name} has been successfully created.`
    })
  } catch (err) {
    next(new ErrorResponse(`Sorry, could not save the new organization`, 404))

// ^ This is the message I get if I violate the validation rule ^

  }
}
  

Документация Sequelize по проверке и ограничениям находится здесь:https://sequelize.org/master/manual/validations-and-constraints.html

Проверка построена на Validatorjs (https://github.com/validatorjs/validator.js ), в котором, к сожалению, также отсутствует практическая информация об использовании объекта проверки. Я предполагаю, что это означает, что это должно быть понятно само по себе, но поскольку я новичок, я потерялся.

Ответ №1:

Я попробовал ту же самую проверку в своем локальном проекте на firstName поле, и я мог бы получить ошибку продолжения, подобную этой

 console.log('err.name', err.name);
console.log('err.message', err.message);
console.log('err.errors', err.errors);
err.errors.map(e => console.log(e.message)) // The name must contain between 2 and 100 characters.
  

вывод проверки

как вы можете видеть, вы можете проверить, err.name есть SequelizeValidationError ли это, а затем выполнить цикл по err.errors массиву и получить message поле для path , а остальные другие свойства также есть.

Пример отображения ошибки:

 const errObj = {};
err.errors.map( er => {
   errObj[er.path] = er.message;
})
console.log(errObj);
  

вы получите объект, подобный

 { 
  firstName: 'The firstName must contain between 2 and 100 characters.',
  lastName: 'The lastName must contain between 2 and 100 characters.' 
}
  

Комментарии:

1. Потрясающе, большое вам спасибо. Таким образом, он передается на общий объект err, который я вижу, и я могу сначала проверить, прежде чем выдавать общую ошибку, если есть err.name свойство, которое соответствует SequelizeValidationError и, если это так, отображает эту ошибку вместо этого. Идеально!

2. Ваше сообщение об ошибке чистое, когда я его пробую, оно похоже на то, users.name must contain between 2 and 100 characters. где users это имя таблицы. Есть идеи, как это изменить?

3. @ShashankAC Используйте msg свойство. Например. isInt: { msg: "Must be an integer number of pennies" }

Ответ №2:

После получения помощи от @Rohit Ambre мой блок catch выглядит следующим образом:

 } catch (err) {
    if (err.name === 'SequelizeValidationError') {
      return res.status(400).json({
        success: false,
        msg: err.errors.map(e => e.message)
      })
    } else {
      next(new ErrorResponse(`Sorry, could not save ${req.body.name}`, 404))
    }
  }
  

Ответ API:

 {
    "success": false,
    "msg": [
        "The name must contain between 2 and 100 characters.",
        "The organization type is not valid."
    ]
}
  

Возможно, было бы полезно добавить ключ для каждого элемента, что-то вроде этого, но что бы я ни делал в блоке catch, кажется, что он выдает мне необработанное предупреждение Promiserejectionwarning:

 catch (err) {
    if (err.name === 'SequelizeValidationError') {
       const errors = err.errors

      const errorList = errors.map(e => {
        let obj = {}
        obj[e] = e.message
        return obj;
      })
      
      return res.status(400).json({
        success: false,
        msg: errorList
      })
    } else {
      next(new ErrorResponse(`Sorry, could not save ${req.body.name}`, 404))
    }
  }
  

Какие-нибудь советы, пожалуйста?

Комментарии:

1. Я обновил свой ответ с форматированием ошибки, проверьте, помогает ли это

Ответ №3:

вы можете выполнить простой флаг —debug в миграции npx sequelize-cli db:migrate —debug

Ответ №4:

серверная часть

 response.err(res, err.errors[0].message ?? 'tidak berhasil menambahkan data', 500);
  

интерфейс

 .catch(error => {
....
        this.fetchLoading = false
        this.$swal({
          title: 'Error!',
          text: `${error.response.data.message ?? 'except your message'}`,
          
  
 "sequelize": "^6.6.5",
    "sequelize-cli": "^6.2.0",