endpoints.ServiceException子类返回400状态代码而不是409

时间:2014-02-27 16:54:48

标签: google-app-engine python-2.7 google-cloud-endpoints

在用于异常处理的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子类的正确方法吗?

1 个答案:

答案 0 :(得分:1)

根据Chris提交的bug report,这似乎是一个错误。