我正在使用带有Java和Google Cloud Endpoints的Google App Engine。在我的JavaScript前端,我正在使用此代码来处理初始化as recommended:
var apisToLoad = 2;
var url = '//' + $window.location.host + '/_ah/api';
gapi.client.load('sd', 'v1', handleLoad, url);
gapi.client.load('oauth2', 'v2', handleLoad);
function handleLoad() {
// this only executes once,
if (--apisToLoad === 0) {
// so this is not executed
}
}
如何在gapi.client.load
失败时检测并处理?目前,我收到一条错误,打印到JavaScript控制台,上面写着:Could not fetch URL: https://webapis-discovery.appspot.com/_ah/api/static/proxy.html)
。也许这是我的错,或者这可能是谷歌的一个暂时问题 - 现在这不是我的担忧。我正试图利用这个机会在客户端很好地处理这些错误。
那么 - 我该如何处理呢?对于错误的调用,handleLoad
没有执行gapi.client.load
,ERR_CONNECTION_TIMED_OUT
似乎没有单独的错误回调(请参阅the documentation),它实际上不会抛出错误(只会将其打印到控制台),它不返回任何东西。我错过了什么?到目前为止,我唯一的想法是设置超时并假设如果在X秒后初始化没有完成则出现错误,但这显然不太理想。
此问题再次出现,这次是在尝试加载oauth
内容时遇到消息{{1}}(这绝对是我无法控制的)。同样,我并没有尝试修复错误,只是确认它值得检测和处理。
答案 0 :(得分:3)
我知道这已经老了,但我偶然发现了这个。您可以轻松地测试失败(至少现在)。
以下是代码:
gapi.client.init({}).then(() => {
gapi.client.load('some-api', "v1", (err) => { callback(err) }, "https://someapi.appspot.com/_ah/api");
}, err, err);
function callback(loadErr) {
if (loadErr) { err(loadErr); return; }
// success code here
}
function err(err){
console.log('Error: ', err);
// fail code here
}
答案 1 :(得分:2)
不幸的是,这里的文档非常无用,调试相关代码并不容易。 gapi.client.load()
显然为每个API插入<iframe>
元素。然后该框架提供必要的功能,并允许通过postMessage()
访问它。从它的外观来看,API没有将load
事件监听器附加到该帧,而是依赖于帧本身来指示它已准备就绪(这将导致回调被触发)。因此,缺少的错误回调是一个固有的问题 - API无法看到失败,因为没有框架可以发出信号。
据我所知,您可以做的最好的事情是将自己的load
事件监听器附加到文档中(事件将从帧中冒出来)并在加载时检查自己。 警告:虽然这可能适用于当前版本的API,但由于该API的实施发生变化,因此无法保证将来继续使用。目前这样的事情应该有效:
var framesToLoad = apisToLoad;
document.addEventListener("load", function(event)
{
if (event.target.localName == "iframe")
{
framesToLoad--;
if (framesToLoad == 0)
{
// Allow any outstanding synchronous actions to execute, just in case
window.setTimeout(function()
{
if (apisToLoad > 0)
alert("All frames are done but not all APIs loaded - error?");
}, 0);
}
}
}, true);
只是重复上面的警告:这段代码做了很多假设。虽然这些假设可能会在这个API中保持一段时间,但也可能是Google会改变某些内容并且此代码将停止运行。甚至可能是Google根据浏览器使用不同的方法,我只在Firefox中测试过。
答案 2 :(得分:1)
这是一种非常黑客的方法,但您可以拦截所有console
消息,检查记录的内容,如果是您关心它的错误消息,请调用另一个函数。
function interceptConsole(){
var errorMessage = 'Could not fetch URL: https://webapis-discovery.appspot.com/_ah/api/static/proxy.html';
var console = window.console
if (!console) return;
function intercept(method){
var original = console[method];
console[method] = function() {
if (arguments[0] == errorMessage) {
alert("Error Occured");
}
if (original.apply){
original.apply(console, arguments)
}
else {
//IE
var message = Array.prototype.slice.apply(arguments).join(' ');
original(message)
}
}
}
var methods = ['log', 'warn', 'error']
for (var i = 0; i < methods.length; i++)
intercept(methods[i])
}
interceptConsole();
console.log('Could not fetch URL: https://webapis-discovery.appspot.com/_ah/api/static/proxy.html');
//alerts "Error Occured", then logs the message
console.log('Found it');
//just logs "Found It"
这里有一个例子 - 我记录两件事,一件是错误信息,另一件是别的。你会看到第一个引起警报,第二个则没有。
在包含interceptConsole
脚本之前,您可能必须运行gapi
函数,因为它可能使其成为自己的控制台副本。
编辑 - 我自己使用了此代码的一个版本,但只记得来自here的版本,因此请将其归功于其应有的位置。
答案 3 :(得分:0)
如果api尚未加载,我使用setTimeout手动触发错误:
console.log(TAG + 'api loading...');
let timer = setTimeout(() => {
// Handle error
reject('timeout');
console.error(TAG + 'api loading error: timeout');
}, 1000); // time till timeout
let callback = () => {
clearTimeout(timer);
// api has loaded, continue your work
console.log(TAG + 'api loaded');
resolve(gapi.client.apiName);
};
gapi.client.load('apiName', 'v1', callback, apiRootUrl);