RSS Impact 是一个支持 Hook 的 RSS 订阅工具,
支持推送通知、Webhook 、下载、BitTorrent、AI 大模型 等多种形式的 Hook。

0%

2020-11-19 express 中处理异步异常和超时

2020-11-19 express 中处理异步异常和超时

参考

express 捕获全局异常的三种方法

如何在 Express4.x 中愉快地使用 async

首先是常见的异常处理中间件。

在异常处理的时候,本人采用了自定义异常的方案,因此可以优先判断是否为自定义异常,如果是则更加优雅的返回错误信息。同时,通过对 res.headersSent 的判断,确保在异常响应之前没有响应客户端,避免 express 报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 这个包

1
npm install express-async-errors --save

使用

1
2
3
require('express-async-errors') // commonjs 写法
//或
import 'express-async-errors' // es6写法

引入之后就能捕获异步函数中的异常了。

例如

1
2
3
router.get('/async-error', async (req, res, next) => {
throw new HttpError(500, '服务器出现异步错误') // 该异常会被捕获
})

最后则是超时处理了。

同样的,也要先判断下是否已经响应请求了,若超时未响应,则返回超时异常。和异常捕获结合使用更佳

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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://blog.cmyr.ltd/archives/8165682e.html
版权声明:转载请注明出处!

坚持原创技术分享,您的支持将鼓励我继续创作!