2016-02-20 10 views
15

Ich habe eine API, die eine nützliche Beschreibung enthält, was schief gelaufen ist, wenn ein Fehler vom Server ausgelöst wird (Status = 500). Die Beschreibung wird als Teil des Antworttextes geliefert. Mein Client-Code, mit Aurelia, ruft die api über aurelia-fetch-client eine generische Methode mit dem Anruf zu tätigen:Fehlerbehandlung für 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()'); 
     } 
    }); 
} 

Bitte beachte, dass ich will, den Server fangen (Abruf- oder Timeout) Fehler in einer konsistenten Art und Weise, und dann throw Zurück nur eine einfache Fehlermeldung an die aufrufende Sicht. Ich kann callRemoteService erfolgreich aufrufen, Fehler zu kontrollieren, wenn ein 500 mit zurückgegeben:

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

Aber ich habe Probleme mit der Antworttext zugreifen, weil die fetch die text() Methode bereitstellt, die ein Versprechen gibt, und das ist zu stören mein sonst so glückliches Versprechen verkettet. Der obige Code funktioniert nicht und hinterlässt einen Uncaught (in promise) Fehler.

Hoffentlich gibt es eine gute Möglichkeit, auf diesen Antworttext zuzugreifen?

+0

hilft das 'catch' vor dem' then' (auf dem oberen code)? – dandavis

+0

@dandavis Ich habe mehrere Varianten ohne Glück ausprobiert. Jeremys Vorschlag, die Versprechenskette innerhalb der "Rasse" zu halten, scheint jedoch zu funktionieren. –

Antwort

11

Dies sollte den Trick:

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

durch die Art und Weise, Ich mag, was Sie mit Promise.race tun - nette Technik!

+1

Aber es lässt die Anfrage offen und ausstehend, oder? Ist das gut? –

+0

nicht sicher, was du meinst –

+1

oh- ich sehe - im Falle eines Timeouts, die Anfrage steht noch aus. Nicht gut, aber keine Antwort dafür, bis sie die Dinge in der Spezifikation sortieren. https://github.com/whatwg/fetch/issues/20 https://github.com/whatwg/fetch/issues/27 –