在用于异常处理的Cloud Endpoints documentation中,建议对endpoints.ServiceException
类进行子类化,以便为409 Conflict错误提供自定义http_status
。另一个问题answer表示Google的基础架构将一些支持的状态代码映射到其他状态代码,但409不是映射状态代码之一。
使用文档中的ConflictException
类:
import endpoints
import httplib
class ConflictException(endpoints.ServiceException):
"""Conflict exception that is mapped to a 409 response."""
http_status = httplib.CONFLICT
当我举起ConflictException
:
@endpoints.method(request_message=apimodels.ClientMessage,
response_message=apimodels.ClientMessage,
name='insert',
path='/clients',
http_method='POST'
)
def insert(self, request):
client = models.Client.get_by_id(request.client_code)
if client:
raise ConflictException('Entity with the id "%s" exists.' % request.client_code)
...
我收到400 Bad Request作为回复:
400 Bad Request
Content-Length: 220
Content-Type: application/json
Date: Thu, 27 Feb 2014 16:11:36 GMT
Server: Development/2.0
{
"error": {
"code": 400,
"errors": [
{
"domain": "global",
"message": "Entity with the id \"FOO\" exists.",
"reason": "badRequest"
}
],
"message": "Entity with the id \"FOO\" exists."
}
}
我在本地dev_appserver上获得相同的400响应代码并部署到App Engine(在1.9.0上)。通过使用App Engine ProtoRPC代码,以下line似乎将所有remote.ApplicationError
类型映射到400状态代码。
如果我更新endpoints.apiserving._ERROR_NAME_MAP
dict以添加我的自定义ConflictException
课程,我可以成功返回409:
import endpoints
import httplib
from endpoints.apiserving import _ERROR_NAME_MAP
class ConflictException(endpoints.ServiceException):
"""Conflict exception that is mapped to a 409 response."""
http_status = httplib.CONFLICT
_ERROR_NAME_MAP[httplib.responses[ConflictException.http_status]] = ConflictException
这是实现endpoints.ServiceException
子类的正确方法吗?