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

时间:2023-01-06 23:10:23

Is it possible to return an 'unsupported' HTTP 4xx status code using a subclass of endpoints.ServiceException?

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

The documentation at https://developers.google.com/appengine/docs/python/endpoints/exceptions first seems to say that it's not possible

https://developers.google.com/appengine/docs/python/endpoints/exceptions上的文档似乎首先说它不可能

Only the HTTP 4xx codes listed below are supported... Use of other HTTP 4xx codes will result in an HTTP 404 response.

仅支持下面列出的HTTP 4xx代码...使用其他HTTP 4xx代码将导致HTTP 404响应。

But then just a little later says that it is?

但是稍后说它是什么?

If you want to create other exception classes for other HTTP status codes, you can do so by subclassing endpoints.ServiceException. The following snippet shows how to create an exception class that represents an HTTP 409 status code...

如果要为其他HTTP状态代码创建其他异常类,可以通过继承endpoints.ServiceException来实现。以下代码段显示了如何创建表示HTTP 409状态代码的异常类...

If I work their snippet into my application I don't seem to be successful -- is this that it isn't possible or simply that I've made an error when using the suggested snippet for custom exception class use?

如果我将他们的代码片段放到我的应用程序中,我似乎没有成功 - 这是不可能的,或者仅仅是在使用建议的代码片段进行自定义异常类时我犯了错误?

My Python file:

我的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])

And the associated YAML:

和相关的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

With valid input sent in the POST request the above is great, but if I alter the POST data to contain the field "i_field" rather than "important_field" then I get a 503 back rather than the expected 422 and the following in the console.

使用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 个解决方案

#1


0  

The documentation says these are the only 404 codes you can map to:

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

400
401
403
404
405
408
409
410
412
413

400 401 403 404 405 408 409 410 412 413

So 422 is out of this range.

所以422超出了这个范围。

The default ones are:

默认的是:

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

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

Try mapping your exception to 405-413

尝试将您的异常映射到405-413

#1


0  

The documentation says these are the only 404 codes you can map to:

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

400
401
403
404
405
408
409
410
412
413

400 401 403 404 405 408 409 410 412 413

So 422 is out of this range.

所以422超出了这个范围。

The default ones are:

默认的是:

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

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

Try mapping your exception to 405-413

尝试将您的异常映射到405-413