如何在云终端中返回自定义错误代码?

如此处所述https://cloud.google.com/appengine/docs/java/endpoints/exceptions Google Cloud Endpoints仅返回一个非常有限的http状态代码范围,即:

HTTP 400 BadRequestException
HTTP 401 UnauthorizedException
HTTP 403 ForbiddenException
HTTP 404 NotFoundException (also: Timeout)
HTTP 405
HTTP 408
HTTP 409 ConflictException
HTTP 410
HTTP 412
HTTP 413

Google建议使用现有的状态代码来返回自定义错误:

“在很多情况下,您可能想要使用通用的HTTP状态码来指示用户的API请求的成功或失败。例如,如果用户试图检索不存在的实体,则可能需要发送HTTP 404状态码表示不存在具有ID:entityId的实体您可以通过抛出由端点库提供的异常来发送此类通用HTTP状态码,如下所示:

String message = "No entity exists with ID: " + entityId;
throw new NotFoundException(message);

谷歌在同一份文件中还指出:

“任何其他HTTP 4xx代码将作为错误404返回”

那有什么问题? 如果我的实体无法找到,我会抛出404,但Google也会抛出404几乎任何其他错误的东西。

除了401,403和409,我可以用它来告诉我的客户确切的错误是什么(授权,禁止或冲突),我需要回到400和404的所有其他状态代码,与导致我的客户永远不知道问题是什么。

当然,我可以包含一个人类可读的错误消息,但是这意味着发生在服务器代码中的RuntimeException,而不是告诉我的客户端它发送的数据有问题。

当然,我也可以使用错误描述的前几位发送应用程序特定的错误代码并发送通用400错误请求,但我想这不是应该如何完成的。

任何输入赞赏。 如何返回客户端可用于解决特定于应用程序的问题的应用程序特定错误代码?


读过以下和其他帖子

  • http://archive.oreilly.com/pub/post/restful_error_handling.html
  • 标准的JSON API响应格式?
  • 我几乎可以说Google的建议是错误的,因为http状态代码和应用程​​序代码之间没有明显的区别。 两者都发生在不同的层上,客户端无法判断它是否提出了错误的请求,如违反合同(例如,调用不存在的端点,本质上是运行时错误),或者传递了错误的id(应用程序层错误)。

    文章提出了以下解决方案:

  • 使用http错误代码:并非总是如上所述
  • 将应用程序错误添加为自定义响应标头:我不会选择此选项,因为它不会出现在日志中,这会使调试变得困难。
  • 总是返回200并将结果包装为JSON(如sockets.io所做的那样):对于端点不可行
  • 我提出了另一个我承认是妥协的解决方案(事实上违反了错误信息),但我认为这是将各个应用程序错误代码最佳合并到云端点​​的最佳解决方案:

  • 我扩展了400个BadRequestException,以便将任何错误消息作为JSON返回。 客户端仍然收到接收http状态码400,但不是String错误消息,而是接收到一个JSON字符串,如下所示:
  • {“code”:400,“message”:“这是一条人类可读的错误消息。” }

    在这里,我有两个选择:要么返回代码400,这意味着这是一个BadRequestException,其中客户端实际违反了合同,或者返回客户端可以轻松解析和处理的任何其他特定于应用程序的代码。

    我的ApplicationException看起来像这样(它使用自定义JSONizer,所以它不会为你这样工作,但你可以使用JSONObject,GSON,Jackson等):

    import com.google.api.server.spi.response.BadRequestException;
    
    public class ApplicationException extends BadRequestException {
        private static final int DEFAULT_APPLICATION_CODE = 400; // use this code for all requests without explicit code
    
        public ApplicationException(int code, String message) {
            super(JsonResponse.build()
                    .add("code", code)
                    .add("message", message)
                    .toString());
        }
        public ApplicationException(String message) {
            super(JsonResponse.build()
                    .add("code", DEFAULT_APPLICATION_CODE)
                    .add("message", message)
                    .toString());
        }
        public ApplicationException(String message, Throwable cause) {
            super(JsonResponse.build()
                    .add("code", DEFAULT_APPLICATION_CODE)
                    .add("message", message)
                    .toString());
        }
    
    }
    

    如果您认为有更好的方法可以做到这一点,我还没有将我的答案标记为正确,因为我希望您继续发布进一步的建议和意见。

    链接地址: http://www.djcxy.com/p/48067.html

    上一篇: How to return custom error codes in Cloud Endpoints?

    下一篇: AngularJS Data Structure: Client side or API?