2015-11-25 12 views
7

Sto tentando di gestire in modo intelligente le risposte di errore/successo dalla nostra API utilizzando le promesse ES2 di fetch &.Il modo più semplice per gestire gli errori personalizzati con il recupero e la promessa ES6

Ecco come ho bisogno di gestire gli stati di risposta:

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 

Quindi, sto lottando con il modo di scrivere questo modo pulito.

ho un po meno di codice stellare lavorando proprio ora che assomiglia a questo:

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) 

ma sembra piuttosto strano di utilizzare pescato due volte e non so come trattare con quel 204 appena ancora.

Inoltre, proprio per chiarire checkStatus e checkErrorStatus fare una cosa simile:

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

Eventuali suggerimenti per pulire questo in su?

+0

Che cos'è 'parseJSON'? – Bergi

+0

oh qualcosa di semplice come questo: funzione di esportazione parseJSON (risposta) { return response.json() } – jasongonzales

+0

Per il caso '422' vedere [questa domanda] (http://stackoverflow.com/q/29473426/1048572) – Bergi

risposta

13

penso che si può scrivere fuori abbastanza facilmente:

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

Sì, questo è bello, hai pensato ad almeno due cose che potrebbero non essermi verificate. E ora che guardo a questo, questo problema sarebbe una buona sfida in un'intervista! – jasongonzales

+0

Solo una piccola nota, il mio setup del webpack si è lamentato del fatto che "gettare err" non era tra parentesi graffe, ma a parte il fatto che la soluzione l'ha schiacciato. – jasongonzales

+0

@jasongonzales: Grazie - ora che me lo dici, il mio parser di sintassi mentale suona anche l'allarme :-) – Bergi

2

Sulla scia soluzione Bergi, si potrebbe considerare meccanizzare la gestione delle risposte con un abbastanza semplice ResponseHandler() oggetto;

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

In uso:

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

si perderebbe l'efficienza di una soluzione hard coded come Bergi di, ma potenzialmente beneficiare di una migliore gestibilità e riutilizzabilità.