Ricerca nel sito web

javascript - Catturare errore da gapi.client.load


Sto utilizzando Google App Engine con Java e Google Cloud Endpoints. Nel mio front-end JavaScript, sto usando questo codice per gestire l'inizializzazione, come raccomandato:

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

Come posso rilevare e gestire quando gapi.client.load fallisce? Attualmente ricevo un errore stampato nella console di JavaScript che dice: Could not fetch URL: https://webapis-discovery.appspot.com/_ah/api/static/proxy.html). Forse è colpa mia, o forse è un problema temporaneo da parte di Google - al momento questa non è la mia preoccupazione. Sto cercando di approfittare di questa opportunità per gestire bene tali errori lato client.

Quindi - come posso gestirlo? handleLoad non viene eseguito per la chiamata che genera errore, gapi.client.load non sembra avere un callback separato per gli errori (vedi la documentazione), in realtà non genera l'errore (lo stampa solo sulla console) e non restituisce nulla. Cosa mi manca? La mia unica idea finora è impostare un timeout e assumere che ci sia stato un errore se l'inizializzazione non si completa dopo X secondi, ma ovviamente questo è meno che ideale.

Modifica :

Questo problema è ricomparso, questa volta con il messaggio ERR_CONNECTION_TIMED_OUT tentando di caricare le cose di oauth (che sono sicuramente fuori dal mio controllo). Ancora una volta, non sto cercando di risolvere l'errore, conferma solo che vale la pena rilevarlo e gestirlo in modo appropriato.

Risposta n. 1

So che questo è vecchio, ma ci sono imbattuto per caso. Puoi facilmente testare un fallimento (almeno adesso).

Ecco il codice:

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
}

Esempio

Risposta n. 2

Sfortunatamente, la documentazione qui è piuttosto inutile e non è esattamente facile fare il debug del codice in questione. Quello che apparentemente fa gapi.client.load() è inserire un elemento <iframe> per ogni API. Quel frame poi fornisce la funzionalità necessaria e permette di accedervi tramite postMessage(). A quanto pare, l'API non collega un listener per l'evento load a quel frame e si affida piuttosto al frame stesso per indicare che è pronto (questo farà sì che il callback venga attivato). Quindi il callback di errore mancante è un problema intrinseco - l'API non può vedere un fallimento perché non ci sarà alcun frame che lo segnali.

Da quello che posso capire, la cosa migliore che puoi fare è allegare il tuo proprio listener per l'evento load al documento (l'evento salirà dai frame) e controllare tu stesso quando vengono caricati. Attenzione: Anche se questo potrebbe funzionare con la versione attuale dell'API, non è garantito che continui a funzionare in futuro, poiché l'implementazione di quell'API potrebbe cambiare. Attualmente qualcosa del genere dovrebbe funzionare:

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);

Solo per ripetere l'avvertimento di sopra: questo codice fa molte ipotesi. Mentre queste ipotesi potrebbero rimanere vere per un po' con questa API, potrebbe anche essere che Google cambi qualcosa e questo codice smetta di funzionare. Potrebbe anche essere che Google utilizzi un approccio diverso a seconda del browser, io ho testato solo in Firefox.