来自gapi.client.load的Catch错误

时间:2014-07-03 21:55:05

标签: javascript google-cloud-endpoints

我正在使用带有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.loadERR_CONNECTION_TIMED_OUT似乎没有单独的错误回调(请参阅the documentation),它实际上不会抛出错误(只会将其打印到控制台),它不返回任何东西。我错过了什么?到目前为止,我唯一的想法是设置超时并假设如果在X秒后初始化没有完成则出现错误,但这显然不太理想。

编辑:

此问题再次出现,这次是在尝试加载oauth内容时遇到消息{{1}}(这绝对是我无法控制的)。同样,我并没有尝试修复错误,只是确认它值得检测和处理。

4 个答案:

答案 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
}

Example

答案 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"

这里有一个例子 - 我记录两件事,一件是错误信息,另一件是别的。你会看到第一个引起警报,第二个则没有。

http://jsfiddle.net/keG7X/

在包含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);