GrpcService 中的 Exception 处理
本节将介绍如何 GrpcService 中的 Exception,并且不会使你的代码杂乱无章。
目录
附加主题
异常处理
如果你熟悉 Spring 的 异常处理, 你应该能看到 gRPC 异常处理与它非常相似。
如下所示:
@GrpcAdvice
public class GrpcExceptionAdvice {
@GrpcExceptionHandler
public Status handleInvalidArgument(IllegalArgumentException e) {
return Status.INVALID_ARGUMENT.withDescription("Your description").withCause(e);
}
@GrpcExceptionHandler(ResourceNotFoundException.class)
public StatusException handleResourceNotFoundException(ResourceNotFoundException e) {
Status status = Status.NOT_FOUND.withDescription("Your description").withCause(e);
Metadata metadata = ...
return status.asException(metadata);
}
}
- 在类中使用
@GrpcAdvice
注解 - 使用
@GrpcExceptionHandler
标记_指定的_ Exception,在抛出指定的 Exception 时,方法将被执行。- 例如: 如果您的应用程序抛出
IllegalArgumentException
异常,那么handleInvalidArgument(IllegalArgumentException e)
方法将会被执行
- 例如: 如果您的应用程序抛出
- 方法必须返回
io.grpc.Status
,StatusException
或StatusRuntimeException
- 如果你处理服务端错误,你可能想要在异常处理程序中记录异常/堆栈跟踪
注意: 原因不会从服务器传送到客户端 - 如 官方文档 所述。因此我们建议将其添加到
状态
/状态异常
以避免在服务端丢失异常信息。
详细说明
异常处理的优先级
在注解中指定的异常类型跟方法参数中的异常类型,他们中间是 and 的关系。
@GrpcExceptionHandler(ResourceNotFoundException.class)
public StatusException handleResourceNotFoundException(ResourceNotFoundException e) {
// your exception handling
}
如果 GrpcExceptionHandler
注解包含至少一个异常类型,那么该方法的异常处理将只会处理这些异常类型。 方法参数中的类型必须与指定的异常类型 “兼容” 如果注解中没有指定任何处理的异常类型,那么所有的方法参数都会被使用。
(“兼容”是指注解中的异常类型是 列出方法参数之一的同一个类或父类)
响应中发送 Metadata
如果你想要在异常响应中发送 metadata,可以看看下面的例子。
@GrpcExceptionHandler
public StatusRuntimeException handleResourceNotFoundException(IllegalArgumentException e) {
Status status = Status.INVALID_ARGUMENT.withDescription("Your description");
Metadata metadata = ...
return status.asRuntimeException(metadata);
}
如果您的响应不需要 Metadata
,只需返回您指定的 Status
。
返回值类型概览
下面是关于 @GrpcExceptionHandler
可能的返回类型和是否支持自定义 Metadata
的概览。
返回值类型 | 支持自定义元数据 |
---|---|
Status |
✗ |
StatusException |
✔ |
StatusRuntimeException |
✔ |