2016-02-20 16 views
15

Ho un'API che include una descrizione utile di cosa è andato storto quando viene sollevato un errore dal server (stato = 500). La descrizione viene come parte del testo di risposta. Il mio codice cliente, utilizzando Aurelia, chiama l'API tramite aurelia-fetch-client utilizzando un metodo generico per effettuare la chiamata:Gestione degli errori per fetch() in Aurelia

function callRemoteService(apiName, timeout) { 
    return Promise.race([ 
    this.http.fetch(apiName), 
    this.waitForServer(timeout || 5000) // throws after x ms 
    ]) 
    .then(response => response.json()) 
    .catch(err => { 
     if (err instanceof Response) { 
      // HERE'S THE PROBLEM..... 
      err.text().then(text => { 
      console.log('Error text from callRemoteService() error handler: ' + text); 
      throw new Error(text) 
      }); 
     } else if (err instanceof Error) { 
      throw new Error(err.message); 
     } else { 
      throw new Error('Unknown error encountered from callRemoteService()'); 
     } 
    }); 
} 

Nota che voglio prendere il server (recupero o timeout) gli errori in modo coerente, e poi throw indietro solo un semplice messaggio di errore alla vista chiamante. Posso richiamare callRemoteService con successo, la cattura di errori quando un 500 viene restituito con:

callRemoteService(this.apiName, this.apiTimeout) 
    .then(data => { 
    console.log('Successfully called \'' + this.apiName + 
     '\'! Result is:\n' + JSON.stringify(data, null, 2)); 
    }) 
    .catch(err => { 
    console.log('Error from \'' + this.apiName + '\':',err) 
    }); 

Tuttavia, sto avendo problemi ad accedere al testo di risposta, perché la fetch fornisce il metodo text() che restituisce una promessa, e che di interferire con la mia promessa altrimenti felice di concatenare. Il codice sopra non funziona, lasciandomi un errore Uncaught (in promise).

Speriamo che ci sia un buon modo per accedere a quel testo di risposta?

+0

mette il 'catch' prima che il' then' (sul codice superiore) aiuti? – dandavis

+0

@dandavis Ho provato diverse varianti senza fortuna. Il suggerimento di Jeremy di mantenere la catena delle promesse all'interno di 'race()' sembra funzionare, comunque. –

risposta

11

Questo dovrebbe fare il trucco:

function callRemoteService(apiName, timeout = 5000) { 
    return Promise.race([ 
    this.http.fetch(apiName) 
     .then(
     r => r.json(), 
     r => r.text().then(text => throw new Error(text)) 
    ), 
    this.waitForServer(timeout) 
    ]); 
} 

a proposito, mi piace quello che stai facendo con Promise.race - bella tecnica!

+1

Ma lascia aperta la richiesta e in attesa, giusto? Quello è buono? –

+0

non so cosa intendi –

+1

oh- Vedo- in caso di un timeout, la richiesta è ancora in sospeso. Non va bene, ma nessuna risposta per questo finché non risolvono le cose nelle specifiche. https://github.com/whatwg/fetch/issues/20 https://github.com/whatwg/fetch/issues/27 –