feat(user): 重构用户消息处理,统一错误和成功消息格式,优化用户相关功能的错误处理
This commit is contained in:
parent
6183aa4da5
commit
4829b5f325
2
app.js
2
app.js
@ -72,7 +72,7 @@ app.use(function (err, req, res, next) {
|
|||||||
res.locals.error = req.app.get('env') === 'development' ? err : {}
|
res.locals.error = req.app.get('env') === 'development' ? err : {}
|
||||||
|
|
||||||
// render the error page
|
// render the error page
|
||||||
res.status(err.status || 500)
|
res.status(err.status || HTTP_STATUS.INTERNAL_SERVER_ERROR)
|
||||||
res.json({
|
res.json({
|
||||||
error: true,
|
error: true,
|
||||||
message: err.message || 'Something went wrong',
|
message: err.message || 'Something went wrong',
|
||||||
|
|||||||
@ -3,73 +3,66 @@
|
|||||||
*/
|
*/
|
||||||
export const HTTP_STATUS = {
|
export const HTTP_STATUS = {
|
||||||
// 信息响应 (100–199)
|
// 信息响应 (100–199)
|
||||||
|
/** @type {number} 继续 */
|
||||||
CONTINUE: 100,
|
CONTINUE: 100,
|
||||||
|
/** @type {number} 协议切换 */
|
||||||
SWITCHING_PROTOCOLS: 101,
|
SWITCHING_PROTOCOLS: 101,
|
||||||
PROCESSING: 102,
|
|
||||||
|
|
||||||
// 成功响应 (200–299)
|
// 成功响应 (200–299)
|
||||||
OK: 200, // 请求成功
|
/** @type {number} 请求成功 */
|
||||||
CREATED: 201, // 请求成功并且服务器创建了新的资源
|
OK: 200,
|
||||||
ACCEPTED: 202, // 已接受
|
/** @type {number} 请求成功并且服务器创建了新的资源 */
|
||||||
NON_AUTHORITATIVE_INFORMATION: 203, // 非权威信息
|
CREATED: 201,
|
||||||
NO_CONTENT: 204, // 没有内容
|
/** @type {number} 已接受 */
|
||||||
RESET_CONTENT: 205, // 重置内容
|
ACCEPTED: 202,
|
||||||
PARTIAL_CONTENT: 206, // 部分内容
|
/** @type {number} 没有内容 */
|
||||||
MULTI_STATUS: 207, // 多状态
|
NO_CONTENT: 204,
|
||||||
ALREADY_REPORTED: 208, // 已报告
|
|
||||||
IM_USED: 226, // 我被使用
|
|
||||||
|
|
||||||
// 重定向消息 (300–399)
|
// 重定向消息 (300–399)
|
||||||
MULTIPLE_CHOICES: 300, // 多种选择
|
/** @type {number} 永久移动 */
|
||||||
MOVED_PERMANENTLY: 301, // 永久移动
|
MOVED_PERMANENTLY: 301,
|
||||||
FOUND: 302, // 查找
|
/** @type {number} 找到 */
|
||||||
SEE_OTHER: 303, // 查看其他位置
|
FOUND: 302,
|
||||||
NOT_MODIFIED: 304, // 未修改
|
/** @type {number} 查看其他位置 */
|
||||||
USE_PROXY: 305, // 使用代理
|
SEE_OTHER: 303,
|
||||||
TEMPORARY_REDIRECT: 307, // 临时重定向
|
/** @type {number} 临时重定向 */
|
||||||
PERMANENT_REDIRECT: 308, // 永久重定向
|
TEMPORARY_REDIRECT: 307,
|
||||||
|
|
||||||
// 客户端错误响应 (400–499)
|
// 客户端错误响应 (400–499)
|
||||||
BAD_REQUEST: 400, // 错误请求
|
/** @type {number} 错误请求 */
|
||||||
UNAUTHORIZED: 401, // 未授权
|
BAD_REQUEST: 400,
|
||||||
PAYMENT_REQUIRED: 402, // 需要付款
|
/** @type {number} 未授权 */
|
||||||
FORBIDDEN: 403, // 禁止
|
UNAUTHORIZED: 401,
|
||||||
NOT_FOUND: 404, // 未找到
|
/** @type {number} 禁止 */
|
||||||
METHOD_NOT_ALLOWED: 405, // 方法禁用
|
FORBIDDEN: 403,
|
||||||
NOT_ACCEPTABLE: 406, // 请求不接受
|
/** @type {number} 未找到 */
|
||||||
PROXY_AUTHENTICATION_REQUIRED: 407, // 需要代理认证
|
NOT_FOUND: 404,
|
||||||
REQUEST_TIMEOUT: 408, // 请求超时
|
/** @type {number} 方法禁用 */
|
||||||
CONFLICT: 409, // 冲突
|
METHOD_NOT_ALLOWED: 405,
|
||||||
GONE: 410, // 已删除
|
/** @type {number} 不接受 */
|
||||||
LENGTH_REQUIRED: 411, // 需要长度
|
NOT_ACCEPTABLE: 406,
|
||||||
PRECONDITION_FAILED: 412, // 前提条件失败
|
/** @type {number} 请求超时 */
|
||||||
PAYLOAD_TOO_LARGE: 413, // 负载过大
|
REQUEST_TIMEOUT: 408,
|
||||||
URI_TOO_LONG: 414, // URI 过长
|
/** @type {number} 冲突 */
|
||||||
UNSUPPORTED_MEDIA_TYPE: 415, // 不支持的媒体类型
|
CONFLICT: 409,
|
||||||
RANGE_NOT_SATISFIABLE: 416, // 请求范围不符合要求
|
/** @type {number} 已删除 */
|
||||||
EXPECTATION_FAILED: 417, // 期望失败
|
GONE: 410,
|
||||||
IM_A_TEAPOT: 418, // 我是一个茶壶
|
/** @type {number} 负载过大 */
|
||||||
MISDIRECTED_REQUEST: 421, // 请求错位
|
PAYLOAD_TOO_LARGE: 413,
|
||||||
UNPROCESSABLE_ENTITY: 422, // 无法处理的实体
|
/** @type {number} URI 过长 */
|
||||||
LOCKED: 423, // 锁定
|
URI_TOO_LONG: 414,
|
||||||
FAILED_DEPENDENCY: 424, // 失败依赖
|
/** @type {number} 不支持的媒体类型 */
|
||||||
TOO_EARLY: 425, // 太早
|
UNSUPPORTED_MEDIA_TYPE: 415,
|
||||||
UPGRADE_REQUIRED: 426, // 升级所需
|
|
||||||
PRECONDITION_REQUIRED: 428, // 必须的前提条件
|
|
||||||
TOO_MANY_REQUESTS: 429, // 请求过多
|
|
||||||
REQUEST_HEADER_FIELDS_TOO_LARGE: 431, // 请求头字段太大
|
|
||||||
UNAVAILABLE_FOR_LEGAL_REASONS: 451, // 因法律原因不可用
|
|
||||||
|
|
||||||
// 服务器错误响应 (500–599)
|
// 服务器错误响应 (500–599)
|
||||||
INTERNAL_SERVER_ERROR: 500, // 内部服务器错误
|
/** @type {number} 服务器错误 */
|
||||||
NOT_IMPLEMENTED: 501, // 尚未实施
|
INTERNAL_SERVER_ERROR: 500,
|
||||||
BAD_GATEWAY: 502, // 错误网关
|
/** @type {number} 未实施 */
|
||||||
SERVICE_UNAVAILABLE: 503, // 服务不可用
|
NOT_IMPLEMENTED: 501,
|
||||||
GATEWAY_TIMEOUT: 504, // 网关超时
|
/** @type {number} 错误网关 */
|
||||||
HTTP_VERSION_NOT_SUPPORTED: 505, // HTTP 版本不受支持
|
BAD_GATEWAY: 502,
|
||||||
VARIANT_ALSO_NEGOTIATES: 506, // 变体也协商
|
/** @type {number} 服务不可用 */
|
||||||
INSUFFICIENT_STORAGE: 507, // 存储不足
|
SERVICE_UNAVAILABLE: 503,
|
||||||
LOOP_DETECTED: 508, // 检测到循环
|
/** @type {number} 网关超时 */
|
||||||
NOT_EXTENDED: 510, // 未扩展
|
GATEWAY_TIMEOUT: 504
|
||||||
NETWORK_AUTHENTICATION_REQUIRED: 511 // 需要网络认证
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
user: {
|
|
||||||
not_found: 'User not found',
|
|
||||||
already_exists: 'User already exists',
|
|
||||||
account_password_not_match: 'Account and password not match',
|
|
||||||
account_not_match: 'Account not match',
|
|
||||||
password_not_match: 'Password not match',
|
|
||||||
password_incorrect: 'Password incorrect'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
19
config/message.js
Normal file
19
config/message.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// messages.js
|
||||||
|
module.exports = {
|
||||||
|
user: {
|
||||||
|
// 成功消息
|
||||||
|
created: 'user created',
|
||||||
|
updated: 'user updated',
|
||||||
|
deleted: 'user deleted',
|
||||||
|
login: 'login successful',
|
||||||
|
logout: 'logout successful',
|
||||||
|
|
||||||
|
// 错误消息
|
||||||
|
not_found: 'user not found',
|
||||||
|
already_exists: 'user already exists',
|
||||||
|
account_password_not_match: 'account and password not match',
|
||||||
|
account_not_match: 'account not match',
|
||||||
|
password_not_match: 'password not match',
|
||||||
|
password_incorrect: 'password incorrect'
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
user: {
|
|
||||||
exist: 'User exist',
|
|
||||||
created: 'User created',
|
|
||||||
updated: 'User updated',
|
|
||||||
deleted: 'User deleted',
|
|
||||||
login: 'Login successful',
|
|
||||||
logout: 'Logout successful'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +1,15 @@
|
|||||||
const { body, validationResult } = require('express-validator')
|
const { body, validationResult } = require('express-validator')
|
||||||
const userService = require('../services/userService')
|
const userService = require('../services/userService')
|
||||||
const FetchResult = require('../common/web/fetchResult')
|
const FetchResult = require('../common/web/fetchResult')
|
||||||
const errorMessages = require('../config/errorMessages')
|
const messages = require('../config/message')
|
||||||
const successMessages = require('../config/successMessages')
|
const { HTTP_STATUS } = require('../common/constant/httpStatus')
|
||||||
|
|
||||||
exports.getAllUsers = async (res) => {
|
exports.getAllUsers = async (res) => {
|
||||||
try {
|
try {
|
||||||
const users = await userService.user_list()
|
const users = await userService.user_list()
|
||||||
return FetchResult.formatResult(res, 200, 'success', users)
|
return FetchResult.formatResult(res, 200, 'success', users)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return FetchResult.formatResult(res, 500, 'Internal server error')
|
return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ exports.createUser = [
|
|||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
return FetchResult.formatResult(
|
return FetchResult.formatResult(
|
||||||
res,
|
res,
|
||||||
400,
|
HTTP_STATUS.BAD_REQUEST,
|
||||||
errors
|
errors
|
||||||
.array()
|
.array()
|
||||||
.map((err) => err.msg)
|
.map((err) => err.msg)
|
||||||
@ -37,13 +37,17 @@ exports.createUser = [
|
|||||||
try {
|
try {
|
||||||
const user = req.body
|
const user = req.body
|
||||||
await userService.create_user(user)
|
await userService.create_user(user)
|
||||||
return FetchResult.formatResult(res, 201, successMessages.user.created)
|
return FetchResult.formatResult(res, HTTP_STATUS.CREATED, successMessages.user.created)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger('Error creating user: ', err)
|
logger('Error creating user: ', err)
|
||||||
if (err.message === errorMessages.user.already_exists) {
|
if (err.message === messages.user.already_exists) {
|
||||||
return FetchResult.formatResult(res, 400, errorMessages.user.already_exists)
|
return FetchResult.formatResult(res, HTTP_STATUS.CONFLICT, messages.user.already_exists)
|
||||||
}
|
}
|
||||||
return FetchResult.formatResult(res, 500, 'Internal server error')
|
return FetchResult.formatResult(
|
||||||
|
res,
|
||||||
|
HTTP_STATUS.INTERNAL_SERVER_ERROR,
|
||||||
|
'Internal server error'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -75,27 +79,30 @@ exports.login = [
|
|||||||
req.session.user = user
|
req.session.user = user
|
||||||
return FetchResult.formatResult(res, 200, successMessages.user.login)
|
return FetchResult.formatResult(res, 200, successMessages.user.login)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message === errorMessages.user.not_found) {
|
if (err.message === messages.user.not_found) {
|
||||||
return FetchResult.formatResult(res, 401, errorMessages.user.account_password_not_match)
|
return FetchResult.formatResult(res, 401, messages.user.account_password_not_match)
|
||||||
}
|
}
|
||||||
return FetchResult.formatResult(res, 500, 'Internal server error')
|
return FetchResult.formatResult(
|
||||||
|
res,
|
||||||
|
HTTP_STATUS.INTERNAL_SERVER_ERROR,
|
||||||
|
'Internal server error'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.getUserExist = async (req, res) => {
|
exports.getUserExist = async (req, res) => {
|
||||||
console.log(req.path)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { account } = req.query
|
const { account } = req.query
|
||||||
|
|
||||||
const exist = await userService.get_user_exist(account)
|
const exist = await userService.get_user_exist(account)
|
||||||
|
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
return FetchResult.formatResult(res, 404, errorMessages.user.not_found)
|
return FetchResult.formatResult(res, 404, messages.user.not_found)
|
||||||
}
|
}
|
||||||
return FetchResult.formatResult(res, 200, successMessages.user.exist)
|
return FetchResult.formatResult(res, 200, successMessages.user.exist)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return FetchResult.formatResult(res, 500, 'Internal server error')
|
logger('Error checking user existence: ', err)
|
||||||
|
return FetchResult.formatResult(res, HTTP_STATUS.INTERNAL_SERVER_ERROR, 'Internal server error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
const UserModel = require('../models/userModel')
|
const UserModel = require('../models/userModel')
|
||||||
const { hashPassword } = require('../utils/hashUtils')
|
|
||||||
|
|
||||||
exports.startTransaction = async () => {
|
exports.startTransaction = async () => {
|
||||||
const seesion = await UserModel.startSession()
|
const seesion = await UserModel.startSession()
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
const userMapper = require('../repositories/userRepository')
|
const userMapper = require('../repositories/userRepository')
|
||||||
const logger = require('morgan')
|
const logger = require('morgan')
|
||||||
const errorMessages = require('../config/errorMessages')
|
const messages = require('../config/messages')
|
||||||
const { comparePassword } = require('../utils/hashUtils')
|
const { comparePassword } = require('../utils/hashUtils')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} account
|
||||||
|
* @param {string} password
|
||||||
|
* @returns {Promise<object>}
|
||||||
|
*/
|
||||||
exports.login = async (account, password) => {
|
exports.login = async (account, password) => {
|
||||||
try {
|
try {
|
||||||
const user = await userMapper.selectUserByAccount(account)
|
const user = await userMapper.selectUserByAccount(account)
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new Error(errorMessages.user.not_found)
|
throw new Error(messages.user.not_found)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isMatch = await comparePassword(password, user.password)
|
const isMatch = await comparePassword(password, user.password)
|
||||||
|
|
||||||
if (!isMatch) {
|
if (!isMatch) {
|
||||||
throw new Error(errorMessages.user.password_incorrect)
|
throw new Error(messages.user.password_incorrect)
|
||||||
}
|
}
|
||||||
|
|
||||||
user.last_login_date = new Date()
|
user.last_login_date = new Date()
|
||||||
@ -23,10 +28,16 @@ exports.login = async (account, password) => {
|
|||||||
|
|
||||||
return user
|
return user
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
logger('Error logging in: ', err)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} account
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
exports.get_user_exist = async (account) => {
|
exports.get_user_exist = async (account) => {
|
||||||
try {
|
try {
|
||||||
return await userMapper.selectUserByAccountExist(account)
|
return await userMapper.selectUserByAccountExist(account)
|
||||||
@ -54,7 +65,7 @@ exports.create_user = async (user) => {
|
|||||||
const check_user = await userMapper.selectUserByAccount(account)
|
const check_user = await userMapper.selectUserByAccount(account)
|
||||||
|
|
||||||
if (check_user) {
|
if (check_user) {
|
||||||
throw new Error(errorMessages.user.already_exists)
|
throw new Error(messages.user.already_exists)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await userMapper.createUser(user)
|
const result = await userMapper.createUser(user)
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
|
import FetchResult from '../common/web/fetchResult.js'
|
||||||
|
|
||||||
exports.authenticateSession = async (req, res, next) => {
|
exports.authenticateSession = async (req, res, next) => {
|
||||||
if (req.session.user) {
|
if (req.session.user) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
res.status(401).json({ error: 'Unauthorized' })
|
return FetchResult.formatResult(res, HTTP_STATUS.UNAUTHORIZED, 'Unauthorized')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user