Express http api 中一致的错误验证响应,使用 mongoose 和 Joi
Consistent error validation responses in Express http api, using mongoose and Joi
我是 Node 后端开发的新手,因为我来自前端。
我正在使用 Express、Mongo、Mongoose 和 Joi 开发一个 http api 来进行输入验证。
我同时使用 Mongoose and Joi 模式验证,后者仅在特定情况下使用,例如 post/put/patch 路由。
在电子邮件字段的 Mongoose 模式中使用 "unique" 规则我偶然发现了以下问题:Mongoose 错误响应与 Joi 的有很大不同。可以想象,应该首选一致的响应,以避免在前端进行复杂的数据解析以在 UI.
中显示错误
这是Mongo针对唯一电子邮件设置错误响应的示例:
{
"errors": {
"email": {
"message": "Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"name": "ValidatorError",
"properties": {
"message": "Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"type": "unique",
"path": "email",
"value": "lorem.ipsum@yahoo.com"
},
"kind": "unique",
"path": "email",
"value": "lorem.ipsum@yahoo.com"
}
},
"_message": "Author validation failed",
"message": "Author validation failed: email: Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"name": "ValidationError"
}
虽然这是 Joi 错误密码错误响应示例:
{
"isJoi": true,
"name": "ValidationError",
"details": [
{
"message": "\"password\" with value \"3\" fails to match the required pattern: /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,32}$/",
"path": [
"password"
],
"type": "string.regex.base",
"context": {
"pattern": {},
"value": "3",
"key": "password",
"label": "password"
}
}
],
"_object": {
"username": "thequickbrownfox",
"first_name": "The Quick",
"last_name": "Brown Fox",
"email": "thequickbrownfox@hotmail.com",
"password": "3"
}
}
请注意,我还使用 Mongoose Unique Validator 来获取 Mongoose 独特的错误消息,而不是默认的 E11000 Mongo 错误,这是非常无语的。
在此类用例中有没有办法获得类似的错误响应?谢谢。
我将从为 express 构建一个中间件错误处理程序开始,它捕获来自 Mongoose 和 Joi 的不同错误响应,并将它们转换为适合您的统一错误响应。
例如,在您的主 Express 应用中:
app.use(function (err, req, res, next) {
if (err) {
let transformedErrorPayload = parseError(err)
res.status(someErrorCode).json(transformedErrorPayload)
}
})
您的转换可能如下所示:
parseError(err) {
if ("isJoi" in err && err.isJoi == true) {
// do stuff with the Joi error
return transformedErrorPayload
} else if ("errors" in err && err.errors instanceof Object) {
// do stuff with Mongoose error
return transformedErrorPayload
}
}
我是 Node 后端开发的新手,因为我来自前端。 我正在使用 Express、Mongo、Mongoose 和 Joi 开发一个 http api 来进行输入验证。
我同时使用 Mongoose and Joi 模式验证,后者仅在特定情况下使用,例如 post/put/patch 路由。
在电子邮件字段的 Mongoose 模式中使用 "unique" 规则我偶然发现了以下问题:Mongoose 错误响应与 Joi 的有很大不同。可以想象,应该首选一致的响应,以避免在前端进行复杂的数据解析以在 UI.
中显示错误这是Mongo针对唯一电子邮件设置错误响应的示例:
{
"errors": {
"email": {
"message": "Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"name": "ValidatorError",
"properties": {
"message": "Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"type": "unique",
"path": "email",
"value": "lorem.ipsum@yahoo.com"
},
"kind": "unique",
"path": "email",
"value": "lorem.ipsum@yahoo.com"
}
},
"_message": "Author validation failed",
"message": "Author validation failed: email: Error, expected 'email' to be unique. Value: 'lorem.ipsum@yahoo.com'",
"name": "ValidationError"
}
虽然这是 Joi 错误密码错误响应示例:
{
"isJoi": true,
"name": "ValidationError",
"details": [
{
"message": "\"password\" with value \"3\" fails to match the required pattern: /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,32}$/",
"path": [
"password"
],
"type": "string.regex.base",
"context": {
"pattern": {},
"value": "3",
"key": "password",
"label": "password"
}
}
],
"_object": {
"username": "thequickbrownfox",
"first_name": "The Quick",
"last_name": "Brown Fox",
"email": "thequickbrownfox@hotmail.com",
"password": "3"
}
}
请注意,我还使用 Mongoose Unique Validator 来获取 Mongoose 独特的错误消息,而不是默认的 E11000 Mongo 错误,这是非常无语的。 在此类用例中有没有办法获得类似的错误响应?谢谢。
我将从为 express 构建一个中间件错误处理程序开始,它捕获来自 Mongoose 和 Joi 的不同错误响应,并将它们转换为适合您的统一错误响应。
例如,在您的主 Express 应用中:
app.use(function (err, req, res, next) {
if (err) {
let transformedErrorPayload = parseError(err)
res.status(someErrorCode).json(transformedErrorPayload)
}
})
您的转换可能如下所示:
parseError(err) {
if ("isJoi" in err && err.isJoi == true) {
// do stuff with the Joi error
return transformedErrorPayload
} else if ("errors" in err && err.errors instanceof Object) {
// do stuff with Mongoose error
return transformedErrorPayload
}
}