打开 NestJS 过滤器的大门吧
嗯..很久没写技术文章了哈哈哈。众所周知,Nestjs自己提供了一个异常过滤器,使用一个ExceptionFilter
类可以在发生问题的时候额外输出多一些内容,那么久比如说:修改返回的数据结构,又或者是碰到错误的时候,及时使用Logger生成日志
如图,就是一个Logger.log返回的信息
从 implements 开始
众所周知,nest提供了一个ExceptionFilter的基础类,而要写出自定义的过滤器,也只需要 implements ExceptionFilter
即可
在类内部,为了捕捉错误等一系列操作,我们要用到catch()
方法,在此处定义两个变量,分别为exception和host
host 变量
其中自然就要对这两个变量做一个注解了,exception我们都知道,但是host将会用到一个叫做「ArgumentsHost」的类
ArugumentsHost 提供了在Express中的request, response, next(或者说封装了他们)
我们大可以用
switchToHttp
方法来获取他们
而目前,我们的代码是这个样子的:
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
//...
}
}
接下来就首先处理一下host吧
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
上面的代码中,我们使用switchToHttp
方法(它的作用是将上下文转变为HTTP),将host转移到了ctx,此时ctx的类型就变成了:HttpArgumentsHost
处理过后,我们就可以在后面使用啦~接下来我们来看看「exception」
exception 变量
那这个就简单了
exception.message
可以获取异常信息exception.getStatus()
可以获取状态码
综合这两条,我们就可以写出来类似于这个的代码
const message = exception.message;
Logger.log('Oops! w(゚Д゚)w 出错了! 错误信息: ' + message);
const errorResponse = {
statusCode: exception.getStatus(),
message: message,
error: message,
url: request.originalUrl,
};
当然这个时候我们只是写好了这些量,但是他们全都没有被真正在返回数据中使用到
而这个时候,我们在前面处理host时出来的「response」就有了用途
我们可以通过response设置返回的状态码、头、错误信息
response.status(status);
response.header('Content-Type', 'application/json; charset=utf-8');
response.send(errorResponse);
哦对,返回的状态码还需要检查一下再去返回,毕竟返回的数据无法确定。其中用到的instanceof是来检测某个对象是不是另一个对象的实例的
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
那么整体下来,代码就如同这样了
整合为一
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
const message = exception.message;
Logger.log('[gSpaceHelper] Oops! w(゚Д゚)w 出错了! 错误信息: ' + message);
const errorResponse = {
statusCode: exception.getStatus(),
message: message,
error: message,
url: request.originalUrl, // 错误的url地址
};
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
// 设置返回的状态码、请求头、发送错误信息
response.status(status);
response.header('Content-Type', 'application/json; charset=utf-8');
response.send(errorResponse);
}
}
提升为全局过滤器
前往main.ts文件,将刚刚写的HttpExceptionFilter引入,接着使用useGlobalsFilters创建一个对象吧
app.useGlobalFilters(new HttpExceptionFilter());