| gRPC Code | gRPC Status | HTTP Status | 설명 |
|---|---|---|---|
| 0 | OK | 200 OK | 성공 |
| 1 | CANCELLED | 499 Client Closed Request | 클라이언트가 요청을 취소함 |
| 2 | UNKNOWN | 500 Internal Server Error | 알 수 없는 서버 오류 |
| 3 | INVALID_ARGUMENT | 400 Bad Request | 잘못된 파라미터 |
| 4 | DEADLINE_EXCEEDED | 504 Gateway Timeout | 시간 초과 |
| 5 | NOT_FOUND | 404 Not Found | 리소스를 찾을 수 없음 |
| 6 | ALREADY_EXISTS | 409 Conflict | 이미 존재함 |
| 7 | PERMISSION_DENIED | 403 Forbidden | 권한 없음 |
| 8 | RESOURCE_EXHAUSTED | 429 Too Many Requests | 요청 과다 또는 리소스 부족 |
| 9 | FAILED_PRECONDITION | 400 Bad Request | 요구 조건 미충족 |
| 10 | ABORTED | 409 Conflict | 트랜잭션 충돌 등 |
| 11 | OUT_OF_RANGE | 400 Bad Request | 범위 초과 |
| 12 | UNIMPLEMENTED | 501 Not Implemented | 아직 구현되지 않음 |
| 13 | INTERNAL | 500 Internal Server Error | 서버 내부 오류 |
| 14 | UNAVAILABLE | 503 Service Unavailable | 서비스 사용 불가 |
| 15 | DATA_LOSS | 500 Internal Server Error | 데이터 손실 |
| 16 | UNAUTHENTICATED | 401 Unauthorized | 인증되지 않음 |
import { RpcException } from '@nestjs/microservices';
import { status } from '@grpc/grpc-js';
throw new RpcException({
code: status.NOT_FOUND,
message: 'Category not found',
});
❗
GrpcStatus가 아니라status를 import해야 합니다:
import { status as GrpcStatus } from '@grpc/grpc-js';
// grpc-to-http.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
NotFoundException,
BadRequestException,
ConflictException,
InternalServerErrorException,
UnauthorizedException,
ForbiddenException,
GatewayTimeoutException,
} from '@nestjs/common';
import { RpcException } from '@nestjs/microservices';
import { status as GrpcStatus, ServiceError } from '@grpc/grpc-js';
@Catch(RpcException)
export class GrpcToHttpFilter implements ExceptionFilter {
catch(exception: RpcException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const error = exception.getError() as ServiceError;
let httpException;
switch (error.code) {
case GrpcStatus.NOT_FOUND:
httpException = new NotFoundException(error.details);
break;
case GrpcStatus.ALREADY_EXISTS:
httpException = new ConflictException(error.details);
break;
case GrpcStatus.INVALID_ARGUMENT:
httpException = new BadRequestException(error.details);
break;
case GrpcStatus.UNAUTHENTICATED:
httpException = new UnauthorizedException(error.details);
break;
case GrpcStatus.PERMISSION_DENIED:
httpException = new ForbiddenException(error.details);
break;
case GrpcStatus.DEADLINE_EXCEEDED:
case GrpcStatus.UNAVAILABLE:
httpException = new GatewayTimeoutException(error.details);
break;
default:
httpException = new InternalServerErrorException(error.details);
}
throw httpException;
}
}
이 필터는 main.ts 또는 컨트롤러 레벨에서 등록해서 사용