64 lines
2.1 KiB
JavaScript
64 lines
2.1 KiB
JavaScript
'use strict';
|
||
|
||
const { API_CODES, ApiError } = require('./api-codes');
|
||
|
||
/**
|
||
* JSON 安全化:BigInt 无法被 JSON.stringify 序列化(直接抛 TypeError);
|
||
* Date 统一转 ISO 字符串。
|
||
* @param {any} value
|
||
* @returns {any}
|
||
*/
|
||
function sanitize(value) {
|
||
if (value === null || value === undefined) return value;
|
||
if (typeof value === 'bigint') {
|
||
return value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value.toString();
|
||
}
|
||
if (value instanceof Date) return value.toISOString();
|
||
if (Array.isArray(value)) return value.map(sanitize);
|
||
if (typeof value === 'object') {
|
||
const out = {};
|
||
for (const [k, v] of Object.entries(value)) out[k] = sanitize(v);
|
||
return out;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
/** 统一成功响应:{ code:0, message:'ok', data }(migration-plan §6.1) */
|
||
function ok(res, data) {
|
||
res.json({ code: API_CODES.OK, message: 'ok', data: sanitize(data) });
|
||
}
|
||
|
||
/**
|
||
* 包装异步路由 handler,自动 catch 转交 error 中间件。
|
||
* 用法:router.get('/x', asyncHandler(async (req,res) => {...}))
|
||
* @param {(req: any, res: any, next: any) => Promise<any>} fn
|
||
*/
|
||
function asyncHandler(fn) {
|
||
return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
|
||
}
|
||
|
||
/** Express 全局错误中间件(4 参数) */
|
||
// eslint-disable-next-line no-unused-vars
|
||
function errorMiddleware(err, req, res, next) {
|
||
if (err instanceof ApiError) {
|
||
return res.status(err.httpStatus).json({ code: err.code, message: err.message, data: null });
|
||
}
|
||
const HTTP_TO_CODE = { 400: 1001, 401: 1002, 403: 1003, 404: 1004, 409: 1005 };
|
||
if (err && typeof err.status === 'number') {
|
||
return res.status(err.status).json({
|
||
code: HTTP_TO_CODE[err.status] || API_CODES.SERVER_ERROR,
|
||
message: err.message || '请求错误',
|
||
data: null,
|
||
});
|
||
}
|
||
console.error('[error]', err && err.stack ? err.stack : err);
|
||
const detail = err?.sqlMessage || err?.message;
|
||
return res.status(500).json({
|
||
code: API_CODES.SERVER_ERROR,
|
||
message: detail ? `服务器错误:${detail}` : '服务器错误',
|
||
data: null,
|
||
});
|
||
}
|
||
|
||
module.exports = { sanitize, ok, asyncHandler, errorMiddleware };
|