2017-01-18 3 views
1

Ich versuche, 500 interne Serverfehler innerhalb Fetch zu behandeln. Wenn ein interner Fehler auftritt, antwortet der Server mit einer Nachricht. Ich möchte diese Nachricht extrahieren.Fetch Versprechen - Return 500 Interna Server Fehler

const req = new Request(url, { 
     method: node.method, 
     mode: 'cors', 
     headers: { 'Content-Type': 'application/json' }, 
     body: JSON.stringify(body), 
    }); 
    fetch(req) 
     .then((response) => { 
     if (response.status === 500) { 
      // res.json extracts the body from the response as a promise, chain 
      // .then on it and throw an error to be caught in the lower catch. 
      response.json() 
      .then((json) => { 
      const { message, stackTrace } = json; 
      throw new ServerException(message, stackTrace); // note 1 
      }) 
      .catch((error) => { 
      return Promise.reject(RawException(error)); // note 2 
      }); 
     } else { 
      return response.json(); 
     } 
     }) 
     .then((json) => { // note 3 
     dispatch(stopLoading()); 
     dispatch(recieveResponse(typeOfRequest, json)); 
     }) 
     .catch((e) => { 
     dispatch(stopLoading()); 
     dispatch(responseError()); 
     dispatch(showError(e.message)); 
     }); 
    }; 

Mein Problem ist, dass der Körper der Antwort zu extrahieren ein neues Versprechen schafft, und ich bin nicht in der Lage die äußereen Versprechen von den Innen einem abzulehnen.

Hinweis 1 löst die Fangmethode des inneren Versprechens aus. Inside Catch, ich habe versucht, einen weiteren Fehler zu werfen, aber es scheint nicht zu funktionieren. Wenn ich throw new RawException(error) auf der zweiten Notizzeile, passiert nichts und die then Methode auf der dritten Notizzeile löst aus. Wenn ich ein abgelehntes Versprechen zurückgebe, wie ich es in dem bereitgestellten Code habe, dann triggert immer noch, aber json ist undefiniert.

Wie mache ich das?

+1

Ist das Problem, dass Sie nicht das erste 'response.json()' zurückgeben? Im Fall von 'response.status === 500' geben Sie eigentlich nichts zurück. Aber du bist in deinem anderen mit einem 'return response.json();'. – zero298

+0

Laut @ zero298, aber nach dem Einfügen einer Rückkehr als 'return response.json(). Dann (...)' in der 500-Fehlerbehandlung benötigen Sie nicht die unmittelbar folgende .catch -Klausel, um eine abgelehnte Versprechung zurückzugeben: das Versprechen wird durch den "Wurf" abgelehnt. – traktor53

+0

@JaromandaX Ich schrieb den Kommentar basierend auf der OP-Beobachtung "Note 1 löst die innere Fangmethode". Wie Sie darauf hinweisen, ist dies möglicherweise nicht immer wahr. Es könnte sogar selten wahr sein. Danke für die Korrektur. – traktor53

Antwort

4

Die Lösung besteht nicht darin, Versprechen zu verschachteln, sondern die .then des äußeren Versprechens mit dem Abschluss des inneren Versprechens zu lösen/zurückzugeben.

if (response.status === 500) { 
    response.json() // response.json returns a promise, we chose to do nothing with its 
    .then((json) => { // conclusion 
    const { message, stackTrace } = json; 
    throw new ServerException(message, stackTrace); // note 1 
    }) 
    .catch((error) => { 
    return Promise.reject(RawException(error)); // note 2 
    }); 
} else { 
    return response.json(); 
} 

Sollte

if (response.status === 500) { 
    return response.json() // return the result of the inner promise, which is an error 
    .then((json) => { 
    const { message, stackTrace } = json; 
    throw new ServerException(message, stackTrace); 
    }); 
} else { 
    return response.json(); 
} 

Die else-Klausel als auch entfernt werden kann, werden, wenn die Syntax bevorzugt. ESLint beklagt sich darüber, dass das andere verschwenderisch sei, aber ich bevorzuge die Art, wie es die Verzweigung des Codes explizit macht.

+0

Ja, das. Btw, wenn Sie rohe Ausnahmen von 'json()' umhüllen wollen, anstatt die Serverausnahmen neu zu wickeln, sollten Sie '.then (({message, stackTrace}) => {neue ServerException werfen (message, stackTrace) ;}, error => {neue RawException (error);}) ''. Siehe [hier über den Unterschied] (http://stackoverflow.com/q/24662289/1048572). – Bergi