2015-07-11 24 views
9

Sto scrivendo un'API per il mio sistema, che sta inviando un XHR al server e restituisce una promessa che dovrebbe essere gestita dal chiamante - finora così buono.Promises e istruzioni generiche .catch()

Per ogni chiamata API devo usare un .then e .catch chiamate, ma di solito (come il 75% del tempo) il .catch riferimenti la stessa funzionalità che stampa semplicemente utilizzando console.error.

La mia domanda è - C'è un modo per allegare un'istruzione di cattura predefinita per ogni promessa che creo? (che diciamo stampe alla console), e per ogni promessa che vorrei gestire ulteriormente il rifiuto, aggiungerei un'altra chiamata .catch (o addirittura la sostituirò)?

esempio semplificato in cui ogni chiamata ha il suo .catch: http://jsbin.com/waqufapide/edit?js,console

non la versione che cerca di implementare il comportamento desiderato di lavoro: http://jsbin.com/nogidugiso/2/edit?js,console

Nel secondo esempio, invece di tornare deferred.promise, mi restituisce un promettere con annessa catch() gestore:

return deferred.promise.catch(function (error) { 
    console.error(error); 
}); 

funzioni Sia then catture e then sono chiamati in quel caso.

Mi rendo conto del Q espone l'evento getUnhandledReasons() funzione ed onerror, ma io in realtà non desidera utilizzare .done() per ogni promessa né costruire una sorta di timer/intervallo di gestire l'elenco di rifiuti non-trattati.

Altre librerie come bluebird espongono gli eventi onPossiblyUnhandledRejection, che devo ammettere è una soluzione un po 'più bella, ma ancora non proprio quello che sto cercando.

+1

Q supporta 'process.on ('unhandledRejection'' dal 1.3, sfortunatamente non ho avuto il tempo di scriverlo per i browser - le richieste pull sarebbero benvenute. Raccomando caldamente bluebird :) –

+0

Perché "onPossiblyUnhandledRejection" non è quello che stai cercando?No, non c'è modo di associare i gestori di errori a * ogni * promessa, e non lo si vuole comunque, ma non esiste un modo reale per rilevare automaticamente i fini della catena di promessa (non meglio di "possibilmente non gestito ..."). – Bergi

+0

@Bergi Sto generando automaticamente tutte le mie promesse in un posto centrale, quindi avrei potuto essere utile semplicemente allegare un gestore di default 'catch'. –

risposta

0

con promesse Bluebird, è possibile chiamare

Promise.onPossiblyUnhandledRejection(function(error){ 
    // Handle error here 
    console.error(error); 
}); 

Con iojs voi hanno il gestore process.on('unhandledRejection') come specificato here. (Vale la pena leggere anche this e this

Per quanto ne so, né promesse, nativo altrove né promesse Q offre questa funzionalità.

+0

Questo ha l'ulteriore vantaggio (rispetto al processo hook) di ignorare ciò che hai fatto solo nella tua istanza bluebird e non a livello globale. –

+0

Penso che OP voglia solo lanciare l'errore nel loro caso. Sono su cellulare quindi non posso rispondere. –

1

Penso che tutto quello che volete fare è rethrow l'eccezione dopo aver 'Ho registrato così altri gestori si occuperà in modo corretto:

return deferred.promise.catch(function (error) { 
    console.error(error); 
    throw e; // rethrow the promise 
}); 
+0

Sì, sembra che faccia il trucco, grazie! –

+0

@GiladArtzi sicuro, questo è proprio come in 'catch' sincrono quando si desidera gestire un errore ma non contrassegnare l'errore come risolto. –

1

Q processo uso NodeJS per alzare unhandledRejection Se non utilizzare NodeJS, è possibile utilizzare questa soluzione:.

// Simulating NodeJS process.emit to handle Q exceptions globally 
process = { 
    emit: function (event, reason, promise) { 
     switch(event) 
     { 
      case 'unhandledRejection': 
       console.error("EXCEPTION-Q> %s", reason.stack || reason) 
       break; 
     } 
    } 
}