2015-11-25 2 views
7

zu behandeln Ich versuche, die Erfolg/Fehler-Antworten von unserer API mit Fetch & ES6 Versprechungen intelligent zu behandeln.Cleanste Möglichkeit, benutzerdefinierte Fehler mit Fetch & ES6 Versprechen

Hier ist, wie ich brauche Antwort Zustände zu behandeln:

204: has no json response, but need to treat as success 
406: should redirect to sign in 
422: has json for error message 
< 400 (but not 204): success, will have json 
>= 400 (but not 422): error, will not have json 

Also, ich habe Schwierigkeiten damit, wie diese sauber zu schreiben.

Ich habe etwas weniger als stellare Code arbeiten jetzt, dass wie folgt aussieht:

fetch() 
    .then(response => checkStatus(response)) 
    .then(parseJSON)       //will throw for the 204 
    .then(data => notify('success', someMsg)) 
    .catch(error => checkErrorStatus(error)) 
    .then(parseJSON) 
    .then(data => notify('error', dataForMsg) 
    .catch(error => notify('error', someGenericErrorMsg) 

Aber es scheint ziemlich seltsam fangen zweimal zu verwenden, und ich weiß nicht, wie mit dem 204 nur noch beschäftigen.

auch nur zu klären checkStatus und checkErrorStatus eine ähnliche Sache tun:

export function checkStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return response 
    } else { 
    let error = new Error(response.statusText) 
    error.response = response 
    throw error 
    } 
} 

function checkErrorStatus(error) { 
    if(error.response.status === 422) { 
    return error.response 
    } else { 
    let error = new Error(response.statusText) 
    error.response = response 
    throw error 
    } 
} 

Irgendwelche Vorschläge für diese Reinigung?

+0

Was ist 'parseJSON'? – Bergi

+0

oh nur etwas einfach so: Export-Funktion parseJSON (Antwort) { zurück Antwort.json() } – jasongonzales

+0

Für die '422' Fall siehe [diese Frage] (http://stackoverflow.com/q/29473426/1048572) – Bergi

Antwort

13

Ich glaube, Sie es schreiben können ziemlich leicht aus:

fetch(…).then(response => { 
    if (response.ok) 
     return response[response.status == 204 ? "text" : "json"](); 
    if (response.status == 422) 
     return response.json().then(err => { throw err; }); 
    if (response.status == 406) 
     var error = new AuthentificationError(response.statusText); // or whatever 
    else 
     var error = new Error(response.statusText) 
    error.response = response 
    throw error; 
}) 
+0

Ja, das ist nett, du hast an mindestens zwei Dinge gedacht, die mir vielleicht nicht eingefallen sind. Und jetzt, wo ich das sehe, wäre dieses Problem eine gute Herausforderung in einem Interview! – jasongonzales

+0

Nur ein kleiner Hinweis, mein Webpack-Setup beschwerte sich darüber, dass "throw err" nicht in geschweiften Klammern steckte, aber ansonsten hat Ihre Lösung es zerquetscht. – jasongonzales

+0

@jasongonzales: Danke - jetzt, wo du es erwähnst, hört auch mein mentaler Syntax-Parser den Alarm :-) – Bergi

2

auf aus der Lösung der Bergi Folge, man bedenkt, könnte die Behandlung von Antworten mit einem recht einfachen ResponseHandler() Objekt Mechanisierung;

function ResponseHandler() { 
    this.handlers = []; 
    this.handlers[0] = function() {}; // a "do nothing" default handler 
} 
ResponseHandler.prototype.add = function(code, handler) { 
    this.handlers[code] = handler; 
}; 
ResponseHandler.prototype.handle = function(response) { 
    var h = this.handlers, 
     s = response.status, 
     series = Math.floor(s/100) * 100; // 100, 200, 300 etc 
    (h[s] || h[series] || h[0])(response); // sniff down the line for a specific/series/default handler, then execute it. 
}; 

Im Einsatz:

// create an instance of ResponseHandler() and add some handlers : 
var responseHandler = new ResponseHandler(); 
responseHandler.add(204, function(response) {...}); // specific handler 
responseHandler.add(422, function(response) {...}); // specific handler 
responseHandler.add(406, function(response) {...}); // specific handler 
responseHandler.add(200, function(response) {...}); // 200 series default handler 
responseHandler.add(400, function(response) {...}); // 400 series default handler 
responseHandler.add(0, function(response) {...}); // your overall default handler 

// then : 
fetch(…).then(response => { responseHandler.handle(response); }); 

Sie würden die Effizienz einer harten codierten Lösung wie Bergi die verlieren, aber möglicherweise von einer verbesserten Handhabbarkeit und Wiederverwertbarkeit profitieren.

Verwandte Themen