返回 AiToEarn
global-exception.filter.ts
根目录 / project / aitoearn-backend / libs / common / src / filters / global-exception.filter.ts
1 import type { Request, Response } from 'express'
2 import type { Observable } from 'rxjs'
3
4 import type { CommonResponse } from '../interfaces'
5 import {
6 ArgumentsHost,
7 Catch,
8 ExceptionFilter,
9 HttpException,
10 InternalServerErrorException,
11 Logger,
12 UnauthorizedException,
13 } from '@nestjs/common'
14 import { of } from 'rxjs'
15 import { AppException } from '../exceptions'
16 import { getCurrentRequestId, getRequestIdFromHeaders } from '../interceptors/propagation.interceptor'
17 import { getExceptionPayload } from '../utils'
18
19 export interface GlobalExceptionFilterOptions {
20 returnBadRequestDetails?: boolean
21 }
22
23 @Catch()
24 export class GlobalExceptionFilter<T> implements ExceptionFilter<T> {
25 protected readonly logger = new Logger(GlobalExceptionFilter.name)
26 constructor(private options: GlobalExceptionFilterOptions = {}) { }
27
28 catch(exception: T, host: ArgumentsHost): void | Observable<CommonResponse<unknown> | void> {
29 if (
30 exception instanceof InternalServerErrorException
31 ) {
32 this.logger.fatal(exception)
33 }
34 else if (exception instanceof UnauthorizedException || exception instanceof AppException) {
35 this.logger.warn(exception)
36 }
37 else if (exception instanceof HttpException) {
38 this.logger.error(exception)
39 }
40 else {
41 this.logger.fatal(exception)
42 }
43
44 const payload = getExceptionPayload(exception, this.options.returnBadRequestDetails)
45
46 return this.handleError(host, {
47 ...payload,
48 timestamp: Date.now(),
49 })
50 }
51
52 handleError(host: ArgumentsHost, payload: CommonResponse<unknown>) {
53 const type = host.getType()
54
55 if (type === 'rpc') {
56 return this.handleRpcError(host, payload)
57 }
58 return this.handleHttpError(host, payload)
59 }
60
61 private handleRpcError(
62 host: ArgumentsHost,
63 payload: CommonResponse<unknown>,
64 ) {
65 const requestId = getCurrentRequestId()
66 return of({
67 ...payload,
68 ...(requestId ? { requestId } : {}),
69 })
70 }
71
72 private handleHttpError(
73 host: ArgumentsHost,
74 payload: CommonResponse<unknown>,
75 ) {
76 const ctx = host.switchToHttp()
77 const request = ctx.getRequest<Request>()
78 const response = ctx.getResponse<Response>()
79 const requestId = getRequestIdFromHeaders(request.headers)
80
81 response.status(200).json({
82 ...payload,
83 ...(requestId ? { requestId } : {}),
84 })
85 }
86 }
87
87 lines TYPESCRIPT