【Python分布式服务框架】gRPC服务异常状态响应
文章目录gRPC服务异常状态响应1. gRPC状态码说明2. 服务中直接使用context响应异常3. 定义中间件响应异常4. 成功状态(StatusCode.OK)gRPC服务异常状态响应gRPC服务中已经为我们申明了状态码,需要在项目中引入grpc.StatusCode文件,我们也只能使用这些状态码进行异常响应,使用未定义的状态码会响应UNKNOWN错误,如果项目中有特殊需求可以考虑定义数据结
·
gRPC服务异常状态响应
gRPC服务中已经为我们申明了状态码,需要在项目中引入grpc.StatusCode文件,我们也只能使用这些状态码进行异常响应,使用未定义的状态码会响应UNKNOWN错误,如果项目中有特殊需求可以考虑定义数据结构来实现。
1. gRPC状态码说明
| 状态码 | 描述 |
|---|---|
| OK | 不是错误;是成功的响应。 |
| CANCELLED | 操作已取消,通常由调用方取消。 |
| UNKNOWN | 未知错误。 |
| INVALID_ARGUMENT | 客户端指定了无效参数。 |
| DEADLINE_EXCEEDED | 操作完成前的截止日期已过期。 |
| NOT_FOUND | 未找到某些请求的实体,如:文件或目录。 |
| ALREADY_EXISTS | 我们试图创建的某些实体,例如:文件或目录已经存在。 |
| PERMISSION_DENIED | 调用方无权执行指定的活动。 |
| UNAUTHENTICATED | 请求没有有效的身份验证凭据活动。 |
| RESOURCE_EXHAUSTED | 某些资源已耗尽,可能是每个用户的配额或者可能整个文件系统的空间不足。 |
| FAILED_PRECONDITION | 操作被拒绝,因为系统未处于状态操作执行所需的。 |
| ABORTED | 操作中止,通常是由于并发问题,如sequencer检查失败、事务中止等。 |
| UNIMPLEMENTED | 此服务中未实现或不支持的操作。 |
| INTERNAL | 表示底层用户期望的一些不变量系统被破坏了。 |
| UNAVAILABLE | 该服务当前不可用。 |
| DATA_LOSS | 无法恢复的数据丢失或损坏。 |
2. 服务中直接使用context响应异常
定义服务
# coding=gbk
from grpc import StatusCode
import greeter_pb2, greeter_pb2_grpc
# 黑名单
DenyUser = ["admin", "administrator"]
class Greeter(greeter_pb2_grpc.GreeterServicer):
async def SayHello(self, request, context):
if request.name in DenyUser:
context.set_code(StatusCode.PERMISSION_DENIED)
context.set_details("失败,用户权限不足")
return context
return greeter_pb2.HelloReply(message=f"Hello {request.name}")

3. 定义中间件响应异常
使用中间件来获取异常时可能需要自定义一组异常类配合使用,才能使返回更加友好。
定义中间件
# coding=gbk
from grpc import StatusCode
from types import FunctionType
from functools import wraps
def wrapper(method):
@wraps(method)
async def wrapped(clf, request, context):
try:
return await method(clf, request, context)
except Exception as e:
context.set_code(StatusCode.UNKNOWN)
context.set_details(f'Grpc ERROR [{e}]')
return context
return wrapped
class ServiceMiddlewareClass(type):
def __new__(meta, classname, bases, class_dict):
new_class_dict = {}
for attribute_name, attribute in class_dict.items():
if isinstance(attribute, FunctionType):
# replace it with a wrapped version
attribute = wrapper(attribute)
new_class_dict[attribute_name] = attribute
return type.__new__(meta, classname, bases, new_class_dict)
定义服务
# coding=gbk
from grpc import StatusCode
import greeter_pb2, greeter_pb2_grpc
from middleware import ServiceMiddlewareClass
# 黑名单
DenyUser = ["admin", "administrator"]
class Greeter(greeter_pb2_grpc.GreeterServicer, metaclass=ServiceMiddlewareClass):
async def SayHello(self, request, context):
if request.name in DenyUser:
raise Exception("失败,用户权限不足")
return greeter_pb2.HelloReply(message=f"Hello {request.name}")

4. 成功状态(StatusCode.OK)
需要注意的是,在python实现的gRPC中是不能直接响应OK状态的,如果context被设置为OK状态客户端实际收到的状态是UNKNOWN状态,也需要考虑定义数据结构来实现。
更多推荐
所有评论(0)