使用Google Endpoints自定义HTTP状态代码

时间:2014-06-11 15:32:55

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

是否可以退回“不受支持的”' HTTP 4xx状态代码使用endpoints.ServiceException?

的子类

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 :(得分: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