-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(client): add grpc to http interceptor
- Loading branch information
1 parent
a7b714d
commit 5b7dbb2
Showing
10 changed files
with
137 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"nestjs-grpc-exceptions": minor | ||
--- | ||
|
||
add grpc to http interceptor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { | ||
ArgumentsHost, | ||
Catch, | ||
ExceptionFilter, | ||
HttpStatus, | ||
} from "@nestjs/common"; | ||
import { RpcException } from "@nestjs/microservices"; | ||
import { HTTP_CODE_FROM_GRPC } from "../utils"; | ||
|
||
@Catch(RpcException) | ||
export class GrpcHttpExceptionFilter implements ExceptionFilter { | ||
catch(exception: any, host: ArgumentsHost) { | ||
const details = JSON.parse(exception.details); | ||
|
||
const ctx = host.switchToHttp(); | ||
const response = ctx.getResponse(); | ||
|
||
const httpCode: number = HTTP_CODE_FROM_GRPC[Number(exception.code)] || 500; | ||
const error = HttpStatus[httpCode]; | ||
|
||
response.json({ | ||
message: details.error, | ||
statusCode: httpCode, | ||
error, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./grpc-server-exception.filter"; | ||
export * from "./grpc-http-exception.filter"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./filters"; | ||
export * from "./exceptions"; | ||
export * from "./interceptors"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { | ||
CallHandler, | ||
ExecutionContext, | ||
HttpException, | ||
HttpStatus, | ||
Injectable, | ||
NestInterceptor, | ||
} from "@nestjs/common"; | ||
import { RpcException } from "@nestjs/microservices"; | ||
import { Observable, throwError } from "rxjs"; | ||
import { catchError } from "rxjs/operators"; | ||
import { HTTP_CODE_FROM_GRPC } from "../utils"; | ||
|
||
@Injectable() | ||
export class GrpcToHttpInterceptor implements NestInterceptor { | ||
intercept( | ||
_context: ExecutionContext, | ||
next: CallHandler<any> | ||
): Observable<any> | Promise<Observable<any>> { | ||
return next.handle().pipe( | ||
catchError((err) => { | ||
if ( | ||
!( | ||
typeof err === "object" && | ||
"details" in err && | ||
err.details && | ||
typeof err.details === "string" | ||
) | ||
) | ||
throwError(() => err); | ||
|
||
const exception = JSON.parse(err.details) as { | ||
error: string | object; | ||
type: string; | ||
exceptionName: string; | ||
}; | ||
|
||
if (exception.exceptionName !== RpcException.name) | ||
throwError(() => err); | ||
|
||
const statusCode = | ||
HTTP_CODE_FROM_GRPC[200] || HttpStatus.INTERNAL_SERVER_ERROR; | ||
|
||
return throwError( | ||
() => | ||
new HttpException( | ||
{ | ||
message: exception.error, | ||
statusCode, | ||
error: HttpStatus[statusCode], | ||
}, | ||
statusCode, | ||
{ | ||
cause: err, | ||
} | ||
) | ||
); | ||
}) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./grpc-to-http.interceptor"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { status as Status } from "@grpc/grpc-js"; | ||
import { HttpStatus } from "@nestjs/common"; | ||
|
||
export const HTTP_CODE_FROM_GRPC: Record<number, number> = { | ||
[Status.OK]: HttpStatus.OK, | ||
[Status.CANCELLED]: HttpStatus.METHOD_NOT_ALLOWED, | ||
[Status.UNKNOWN]: HttpStatus.BAD_GATEWAY, | ||
[Status.INVALID_ARGUMENT]: HttpStatus.UNPROCESSABLE_ENTITY, | ||
[Status.DEADLINE_EXCEEDED]: HttpStatus.REQUEST_TIMEOUT, | ||
[Status.NOT_FOUND]: HttpStatus.NOT_FOUND, | ||
[Status.ALREADY_EXISTS]: HttpStatus.CONFLICT, | ||
[Status.PERMISSION_DENIED]: HttpStatus.FORBIDDEN, | ||
[Status.RESOURCE_EXHAUSTED]: HttpStatus.TOO_MANY_REQUESTS, | ||
[Status.FAILED_PRECONDITION]: HttpStatus.PRECONDITION_REQUIRED, | ||
[Status.ABORTED]: HttpStatus.METHOD_NOT_ALLOWED, | ||
[Status.OUT_OF_RANGE]: HttpStatus.PAYLOAD_TOO_LARGE, | ||
[Status.UNIMPLEMENTED]: HttpStatus.NOT_IMPLEMENTED, | ||
[Status.INTERNAL]: HttpStatus.INTERNAL_SERVER_ERROR, | ||
[Status.UNAVAILABLE]: HttpStatus.NOT_FOUND, | ||
[Status.DATA_LOSS]: HttpStatus.INTERNAL_SERVER_ERROR, | ||
[Status.UNAUTHENTICATED]: HttpStatus.UNAUTHORIZED, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./error-object"; | ||
export * from "./http-codes-map"; |