feat: add exception filter
This commit is contained in:
parent
353213c6bd
commit
636995bcd1
@ -5,6 +5,7 @@ import { SwaggerModule } from '@nestjs/swagger'
|
|||||||
|
|
||||||
import { AppModule } from './core/app.module'
|
import { AppModule } from './core/app.module'
|
||||||
import { getCorsConfig, swaggerConfig, validationPipe } from './core/config'
|
import { getCorsConfig, swaggerConfig, validationPipe } from './core/config'
|
||||||
|
import { GrpcExceptionFilter } from './shared/filters'
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule)
|
const app = await NestFactory.create(AppModule)
|
||||||
@ -13,6 +14,7 @@ async function bootstrap() {
|
|||||||
const config = app.get(ConfigService)
|
const config = app.get(ConfigService)
|
||||||
|
|
||||||
app.useGlobalPipes(validationPipe)
|
app.useGlobalPipes(validationPipe)
|
||||||
|
app.useGlobalFilters(new GrpcExceptionFilter())
|
||||||
|
|
||||||
app.enableCors(getCorsConfig(config))
|
app.enableCors(getCorsConfig(config))
|
||||||
|
|
||||||
|
|||||||
1
src/shared/enums/index.ts
Normal file
1
src/shared/enums/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './rpc-status.enum'
|
||||||
19
src/shared/enums/rpc-status.enum.ts
Normal file
19
src/shared/enums/rpc-status.enum.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
export enum RpcStatus {
|
||||||
|
OK = 0,
|
||||||
|
CANCELED = 1,
|
||||||
|
UNKNOWN = 2,
|
||||||
|
INVALID_ARGUMENTS = 3,
|
||||||
|
DEADLINE_EXCEEDED = 4,
|
||||||
|
NOT_FOUND = 5,
|
||||||
|
ALREADY_EXISTS = 6,
|
||||||
|
PERMISION_DENIED = 7,
|
||||||
|
RESOURSE_EXHAUSED = 8,
|
||||||
|
FAILED_PRECONDITION = 9,
|
||||||
|
ABORTED = 10,
|
||||||
|
OUT_OF_RANGE = 11,
|
||||||
|
UNIMPLEMENTED = 12,
|
||||||
|
INTERNAL = 13,
|
||||||
|
UNAVAILABLE = 14,
|
||||||
|
DATA_LOSS = 15,
|
||||||
|
UNAUTHENTICATED = 16
|
||||||
|
}
|
||||||
57
src/shared/filters/grpc-exception.filter.ts
Normal file
57
src/shared/filters/grpc-exception.filter.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import {
|
||||||
|
ArgumentsHost,
|
||||||
|
Catch,
|
||||||
|
ExceptionFilter,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus
|
||||||
|
} from '@nestjs/common'
|
||||||
|
import type { Response } from 'express'
|
||||||
|
|
||||||
|
import { grpcToHttpStatus } from '../utils'
|
||||||
|
|
||||||
|
type GrpcException = {
|
||||||
|
code: number
|
||||||
|
details: string
|
||||||
|
}
|
||||||
|
|
||||||
|
@Catch()
|
||||||
|
export class GrpcExceptionFilter implements ExceptionFilter {
|
||||||
|
public catch(exception: unknown, host: ArgumentsHost) {
|
||||||
|
console.log('filter host', host)
|
||||||
|
console.log('filter exception', exception)
|
||||||
|
const ctx = host.switchToHttp()
|
||||||
|
const response = ctx.getResponse<Response>()
|
||||||
|
|
||||||
|
if (this.isGrpcException(exception)) {
|
||||||
|
const status =
|
||||||
|
grpcToHttpStatus[exception.code] || HttpStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
|
return response.status(status).json({
|
||||||
|
statusCode: status,
|
||||||
|
message: exception.details || 'gRPC Error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception instanceof HttpException) {
|
||||||
|
const status = exception.getStatus()
|
||||||
|
return response.status(status).json({
|
||||||
|
statusCode: status,
|
||||||
|
message: exception.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
message: 'Internal Server Error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private isGrpcException(exception: unknown): exception is GrpcException {
|
||||||
|
return Boolean(
|
||||||
|
exception &&
|
||||||
|
typeof exception === 'object' &&
|
||||||
|
'code' in exception &&
|
||||||
|
'details' in exception
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/shared/filters/index.ts
Normal file
1
src/shared/filters/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './grpc-exception.filter'
|
||||||
23
src/shared/utils/grpc-to-http-status.ts
Normal file
23
src/shared/utils/grpc-to-http-status.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { HttpStatus } from '@nestjs/common'
|
||||||
|
|
||||||
|
import { RpcStatus } from '../enums'
|
||||||
|
|
||||||
|
export const grpcToHttpStatus: Record<number, number> = {
|
||||||
|
[RpcStatus.OK]: HttpStatus.OK,
|
||||||
|
[RpcStatus.CANCELED]: 499,
|
||||||
|
[RpcStatus.UNKNOWN]: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
[RpcStatus.INVALID_ARGUMENTS]: HttpStatus.BAD_REQUEST,
|
||||||
|
[RpcStatus.DEADLINE_EXCEEDED]: HttpStatus.GATEWAY_TIMEOUT,
|
||||||
|
[RpcStatus.NOT_FOUND]: HttpStatus.NOT_FOUND,
|
||||||
|
[RpcStatus.ALREADY_EXISTS]: HttpStatus.CONFLICT,
|
||||||
|
[RpcStatus.PERMISION_DENIED]: HttpStatus.FORBIDDEN,
|
||||||
|
[RpcStatus.RESOURSE_EXHAUSED]: HttpStatus.TOO_MANY_REQUESTS,
|
||||||
|
[RpcStatus.FAILED_PRECONDITION]: HttpStatus.BAD_REQUEST,
|
||||||
|
[RpcStatus.ABORTED]: HttpStatus.CONFLICT,
|
||||||
|
[RpcStatus.OUT_OF_RANGE]: HttpStatus.BAD_REQUEST,
|
||||||
|
[RpcStatus.UNIMPLEMENTED]: HttpStatus.NOT_IMPLEMENTED,
|
||||||
|
[RpcStatus.INTERNAL]: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
[RpcStatus.UNAVAILABLE]: HttpStatus.SERVICE_UNAVAILABLE,
|
||||||
|
[RpcStatus.DATA_LOSS]: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
[RpcStatus.UNAUTHENTICATED]: HttpStatus.UNAUTHORIZED
|
||||||
|
}
|
||||||
1
src/shared/utils/index.ts
Normal file
1
src/shared/utils/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './grpc-to-http-status'
|
||||||
Loading…
x
Reference in New Issue
Block a user