参考
首先是常见的异常处理中间件。
在异常处理的时候,本人采用了自定义异常的方案,因此可以优先判断是否为自定义异常,如果是则更加优雅的返回错误信息。同时,通过对 res.headersSent
的判断,确保在异常响应之前没有响应客户端,避免 express 报错
import express, { Request, Response, NextFunction } from 'express'
import { HttpError } from '@/models/HttpError'
import { HttpStatusCode } from '@/models/HttpStatusCode'
import { ResponseDto } from '@/models/ResponseDto'
import { IS_DEBUG } from '@/config'
import { Log } from '@/utils'
export function catchError(err: any, req: Request, res: Response, next: NextFunction) {
let message: any = 'Unknown Error'
let statusCode = HttpStatusCode.INTERNAL_SERVER_ERROR //500
if (err instanceof HttpError) {
message = err.message
statusCode = err.statusCode
} else if (err instanceof Error) {
// 开发阶段打印堆栈信息,否则打印 message
message = IS_DEBUG ? err.stack : err.message
} else if (typeof err === 'string') {
message = err
}
if (statusCode >= 500) {
Log.error(message)
}
if (!res.headersSent) { // 若请求还未结束,则回复错误
res.status(statusCode).json(new ResponseDto({
statusCode,
message
}))
}
}
接下来是捕获异步异常,这里采用 express-async-errors
这个包
npm install express-async-errors --save
使用
require('express-async-errors') // commonjs 写法
//或
import 'express-async-errors' // es6写法
引入之后就能捕获异步函数中的异常了。
例如
router.get('/async-error', async (req, res, next) => {
throw new HttpError(500, '服务器出现异步错误') // 该异常会被捕获
})
最后则是超时处理了。
同样的,也要先判断下是否已经响应请求了,若超时未响应,则返回超时异常。和异常捕获结合使用更佳
import express, { Request, Response, NextFunction } from 'express'
import { HttpStatusCode } from '@/models/HttpStatusCode'
import { TIMEOUT } from '@/config'
export async function handleTimeout(req: Request, res: Response, next: NextFunction) {
const time = TIMEOUT
// 设置所有HTTP请求的服务器响应超时时间
res.setTimeout(time, () => {
const statusCode = HttpStatusCode.REQUEST_TIMEOUT // 409
if (!res.headersSent) { // 若请求还未结束,则回复超时
res.status(statusCode).json({
statusCode,
message: '请求响应超时'
})
}
})
next()
}
参考代码:https://github.com/CaoMeiYouRen/express-template
- 本文链接: https://wp.cmyr.ltd/archives/handle-asynchronous-exceptions-and-timeouts-in-express
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
欢迎关注我的其它发布渠道
发表回复
要发表评论,您必须先登录。