Google Endpoints自定义HTTP状态码

2 投票
1 回答
528 浏览
提问于 2025-04-18 09:26

是否可以通过一个 endpoints.ServiceException 的子类返回一个“不支持”的 HTTP 4xx 状态码呢?

文档在 https://developers.google.com/appengine/docs/python/endpoints/exceptions首先似乎说这是不可能的。

只有下面列出的 HTTP 4xx 代码是支持的……使用其他 HTTP 4xx 代码将导致返回 HTTP 404 响应。

但接下来又说可以?

如果你想为其他 HTTP 状态码创建其他异常类,可以通过继承 endpoints.ServiceException 来实现。下面的代码片段展示了如何创建一个表示 HTTP 409 状态码的异常类……

如果我把他们的代码片段放到我的应用中,似乎没有成功——这是因为不可能,还是我在使用建议的代码片段时出了错呢?

我的 Python 文件:

# Standard library imports import httplib

# 3rd party imports import endpoints from protorpc import messages from protorpc import message_types from protorpc import remote


package = 'Unprocessable'


class UnprocessableEntityException(endpoints.ServiceException):
    """Unprocessable Entity exception that is mapped to a 422 response."""
    http_status = httplib.UNPROCESSABLE_ENTITY


class ACustomMessage(messages.Message):
    """Greeting that stores a message."""
    important_field = messages.StringField(1)


def process_important_field(important_field):
    a = important_field * 1

@endpoints.api(name='main', version='v1') class UnprocesableTestHandler(remote.Service):
    """ This class handles the creation of entities from a user for storage in
    the data store.
    """

    @endpoints.method(
        ACustomMessage, ACustomMessage, path='test', 
        http_method='POST', name='test.notprocessable'
    )
    def test_improcessable(self, request):
        important_field=request.important_field

        try:
            process_important_field(important_field)
        except TypeError:
            raise UnprocessableEntityException()

        return ACustomMessage(important_field=important_field)

APPLICATION = endpoints.api_server([UnprocesableTestHandler])

相关的 YAML 文件:

application: unprocessable
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
# Endpoints handler
- url: /_ah/spi/.*
  script: main.APPLICATION

libraries:
- name: endpoints
  version: 1.0

当我在 POST 请求中发送有效输入时,上面的代码很好,但如果我把 POST 数据中的字段改为 "i_field" 而不是 "important_field",那么我得到的是 503,而不是预期的 422,并且控制台中显示以下内容。

ERROR    2014-06-11 15:29:08,686 service.py:191] Encountered unexpected error from ProtoRPC method implementation: KeyError (422)
Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/wsgi/service.py", line 181, in protorpc_service_app
    response = method(instance, request)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/endpoints-1.0/endpoints/api_config.py", line 1329, in invoke_remote
    return remote_method(service_instance, request)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/remote.py", line 412, in invoke_remote_method
    response = method(service_instance, request)
  File "/Users/saffy/Desktop/422Example/main.py", line 43, in test_improcessable
    raise UnprocessableEntityException()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/endpoints-1.0/endpoints/api_exceptions.py", line 31, in __init__
    httplib.responses[self.http_status])
KeyError: 422

1 个回答

0

文档上说,这些是你可以映射到的唯一404代码:

400
401
403
404
405
408
409
410
412
413

所以422这个代码不在这个范围内。

默认的代码有:

endpoints.BadRequestException HTTP 400
endpoints.UnauthorizedException HTTP 401
endpoints.ForbiddenException HTTP 403
endpoints.NotFoundException HTTP 404

试着把你的异常映射到405到413之间的代码。

撰写回答