捕获 GoogleJsonResponseException 但 e.getDetails() 返回 null

Posted

技术标签:

【中文标题】捕获 GoogleJsonResponseException 但 e.getDetails() 返回 null【英文标题】:Catching GoogleJsonResponseException but e.getDetails() returns null 【发布时间】:2014-10-24 14:39:41 【问题描述】:

我有一个非 android Java 应用程序一个接一个地上传数千个文件。

对于每个插入,我都像这样实现指数回退:

Random randomGenerator = new Random();
        for(int i = 0; i < 5; i++) 
            try 
                return service.files().insert(body, mediaContent).execute();
             catch(GoogleJsonResponseException e) 
                if (e.getDetails().getCode() == 500
                        || e.getDetails().getCode() == 501
                        || e.getDetails().getCode() == 502
                        || e.getDetails().getCode() == 503
                        || e.getDetails().getCode() == 504
                        || e.getDetails().getCode() == 403) 
                    Thread.sleep((1 << i) * 1000
                            + randomGenerator.nextInt(1001));
                 else 
                    // error besides 5xx
                    throw e;
                 
             catch (HttpResponseException e) 
                if (e.getStatusCode() == 500 || e.getStatusCode() == 501
                        || e.getStatusCode() == 502 || e.getStatusCode() == 503
                        || e.getStatusCode() == 504
                        || e.getStatusCode() == 403) 
                    Thread.sleep((1 << i) * 1000
                            + randomGenerator.nextInt(1001));
                 else 
                    // error besides 5xx
                    throw e;
                
             catch (SocketTimeoutException e) 
                Thread.sleep((1 << i) * 1000 + randomGenerator.nextInt(1001));
            

问题来了:

我的应用程序多次捕获 GoogleJsonResponseException,但 e.getDetails() 返回 null,因此在检查错误代码时出现空指针异常。

根据谷歌文档http://javadoc.google-api-java-client.googlecode.com/hg/1.6.0-beta/com/google/api/client/googleapis/json/GoogleJsonResponseException.html#getDetails()

Returns the Google JSON error details or null for none (for example if response is not JSON).

所以基本上,我正在捕捉GoogleJsonResponseException,但没有 JSON。

为什么我可以捕捉到GoogleJsonResponseException,而实际上并没有任何 Json 与之关联?为什么它没有抓住HttpResponseException

我希望我的应用能够在 Json 返回时捕获/使用它,但是当 GoogleJsonResponseException 甚至不能保证返回 Json 时,我不知道如何可靠地做到这一点。

有什么建议吗?

我是否应该只使用 HttpResponseException 可靠地检查 statusCode,然后查看 getMessage() 以查看是否有 JSON?

或者我应该只使用GoogleJsonResponseException,但调用它的父HttpResponseException 方法getStatusCode() 来查看状态代码,如果我真的 想要检查/潜入任何可能的情况,只能使用getDetails() json?

【问题讨论】:

这个指数退避使用 Drive API v2 Client lib(1.19.0) 并且基于 Google 当前的 Java 代码示例developers.google.com/drive/web/handle-errors 我认为 Google 需要更新此页面...跨度> 您确实需要捕获 403 来处理流量控制,并且您需要跟踪 http 以查看网络上发生了什么。我建议你把你的问题发到groups.google.com/forum/#!forum/google-http-java-client 我正在检查的确切状态代码是无关紧要的——问题集中在GoogleJsonResponseException.getDetails() 返回的null 上。感谢您提供谷歌论坛链接...我会尝试的。 我同意。问题的存在是因为 Google 仅根据 REST API/JSON 的 spec 自动生成 SDK,并且不处理 API 的 behaviour。恕我直言,如果触发了流控制 403,则 403 标头应包括事务 ID 和退避时间。然后,我们的应用程序确切地知道要回退多长时间,并且可以重新提交相同的尝试,Drive 可以根据 tx-id 进行复制。我相信 Dropbox 至少做了一部分。 backoff-retry 是 Drive 的彩票。有些错误很难,所以世界上所有的退避重试都无济于事,反而会破坏用户体验。其他错误是暂时的,将在后续尝试中成功。最好通过自愿节流来完全避免流量控制问题。不幸的是,文档或 http 响应几乎没有帮助您确定哪种策略最有效。具有讽刺意味的是,我曾经问过 Google 完全相同的问题,答案或多或少是“不知道,你告诉我们”。 【参考方案1】:

我会将其作为答案发布,以便为处于相同位置的人提供,即使它没有解决您提出的具体问题。

一些建议

    如果您上传的文件超过 30 个,则会遇到流量控制问题。驱动器的流量控制已损坏,因此您应该自愿节流而不是成为受害者。见403 rate limit on insert sometimes succeeds和403 rate limit after only 1 insert per second

    启用 http 日志记录(有关操作方法,请参阅 Java httpcliebnt 的 code.google.com 页面)。这至少可以让您看到响应是什么,并可能提供一些关于如何最好地捕获异常的线索。

    您链接到的页面是 1.6 版。 afaik 该库目前为 1.19,因此请检查您使用的是最新的库和最新的文档

更令人困惑的是存在三个独立的库。

    堆栈的底部是http 库。 https://code.google.com/p/google-http-java-client/ 上面是通用的api库。 https://code.google.com/p/google-api-java-client/ 和一个 oauth 库 https://code.google.com/p/google-oauth-java-client/ 顶部是使用新 API 基础架构的各种 Google 服务的库。所以例如。驱动器库位于https://developers.google.com/api-client-library/java/apis/drive/v2

【讨论】:

感谢您的回复... Java google drive api 的文档确实让我感到困惑。我不知道最有效的文档在哪里。在这里:javadoc.google-api-java-client.googlecode.com/hg/1.6.0-beta/com/… 或者在这里:developers.google.com/resources/api-libraries/documentation/… 似乎有很多在 Google Drive SDK/Apps 中没有明确或没有详细记录...感谢您提供帮助跨度>

以上是关于捕获 GoogleJsonResponseException 但 e.getDetails() 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

捕获组之前或捕获组之后的正则表达式,具有单个捕获组

第18课 捕获机制及陷阱

为啥基类捕获块捕获派生类对象?

为啥使用 Bash 只读变量捕获输出无法捕获返回码 $?

Java 正则表达式之捕获组

在 C++ 中通过指针捕获异常