捕获 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的主要内容,如果未能解决你的问题,请参考以下文章