Quali sono le migliori pratiche per la gestione degli errori JavaScript?


137

Sto cercando di iniziare a fare il mio JavaScript un po 'più a prova d'errore, e mi sto trovando un sacco di documentazione sull'uso try, catch, finally, e throw, ma io non sto trovando una tonnellata di consigli da esperti su quando e dove buttare gli errori.

  • Ogni parte di codice dovrebbe essere racchiusa in un tentativo / cattura?
  • Ci sono altri consigli come questo a che punto devono essere colti gli errori?
  • Ci sono svantaggi nell'aumentare gli errori invece di far fallire silenziosamente il codice nella produzione?
  • Questo è stato toccato su SO per quanto riguarda le implementazioni, ma gli errori JS di registrazione server sono una strategia efficace?
  • Qualcos'altro che dovrei sapere, riguardo agli errori di intrappolamento nella mia applicazione?

Sono anche completamente un gioco per ascoltare libri che contengono grandi capitoli o spiegazioni approfondite sulla gestione degli errori. JavaScript eloquente tocca la questione, ma non è molto prescrittivo o supponente sulla questione.

Grazie per qualsiasi consiglio tu possa dare!


Dipende sicuramente da quanto spettacolare fallisci se qualcosa va storto e dal volume di possibili messaggi di errore. Non vuoi fallire perché la tua directory di registrazione degli errori è piena ora vero? - Hai guardato qui? stackoverflow.com/search?q=error+logging+javascript
mplungjan

@mplungjan - Ho fatto una scansione delle risposte lì, ma non mi è sembrato molto canonico, e le ricerche per la gestione degli errori Javascript / le migliori pratiche di eccezione non hanno prodotto nulla, quindi ho pensato che potesse essere utile cercare di sollecitare alcuni pensieri condensati, sia per il mio comprensione e futuri ricercatori. Forse questo è un argomento in cui la prescrizione delle migliori pratiche non è il più possibile, ma ogni situazione è altamente unica?
Joshua Cody,

1
"Ogni parte di codice deve essere racchiusa in un tentativo / cattura?" Ovviamente no. C'è un sacco di codice che sai che funzionerà sempre (supponendo che tu lo provi, ovviamente, ma il punto di provare / catturare non è catturare o sorvolare gli errori di codifica). Avvolgere solo il codice che potrebbe non riuscire a volte a causa di qualcosa al di fuori del suo controllo, in genere cose come l'accesso alle risorse, ecc. Nota: alcune cose che possono fallire hanno la gestione degli errori integrata, ad esempio, non mi preoccuperei di codificare Ajax da zero quando ci sono molte librerie che lo fanno che gestiscono i problemi tra browser e consentono di specificare una funzione del gestore degli errori.
nnnnnn,

1
Questa è una buona domanda Josh, +1. C'è un sacco di consigli sintattici in giro, ma come dici tu è la parte facile. Viene toccato nella risposta di questa domanda ( stackoverflow.com/questions/2825427/… ) in cui viene spiegato che le eccezioni non sono così comunemente utilizzate in JS e vengono fornite le ragioni.
Whitneyland,

Risposte:


63

Una serie estremamente interessante di diapositive sulla gestione degli errori JavaScript aziendale è disponibile all'indirizzo http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/

In breve riassume:

  1. Supponiamo che il tuo codice fallisca
  2. Registra errori sul server
  3. Tu, non il browser, gestisci gli errori
  4. Identificare dove potrebbero verificarsi errori
  5. Lancia i tuoi errori
  6. Distingue errori fatali contro non fatali
  7. Fornire una modalità di debug

Le diapositive sono molto più dettagliate e molto probabilmente ti daranno una direzione.

AGGIORNARE

La presentazione di cui sopra è disponibile qui: http://www.slideshare.net/nzakas/enterprise-javascript-error-handling-presentation


24
Il collegamento Devhands è interrotto.
Ryan Gates,

7
A quelli che hanno letto questo nel 2017, direi che non otterrai molto valore dalle diapositive: questo riepilogo ti fornisce il 90% delle informazioni. Sono ancora informazioni preziose. Saluti!
Philippe Hebert,

29

Nicholas Zakas di Yahoo! fame ha fatto un discorso su Enterprise Error Handling ( diapositive ) all'Ajax Experience 2008, in cui ha proposto qualcosa del genere:

function log(sev,msg) {
    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

// usage
log(1, "Something bad happened.")

// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) {
    log(1, msg);
    return true;
}

Un anno dopo, Nicholas Zakas ha pubblicato un aggiornamento sul suo blog che includeva un modello intelligente per iniettare automaticamente il codice di gestione degli errori nell'ambiente di produzione (utilizzando la programmazione orientata all'aspetto).

Quando inizi a registrare le chiamate window.error, noterai due cose:

  1. Se il tuo sito è abbastanza complesso, registrerai molti errori
  2. Vedrai un mucchio di inutili messaggi "window.error in undefined: 0"

Ridurre il torrent delle voci di registro è semplice quanto testare la gravità e / o un numero casuale prima di accedere al server:

function log(sev,msg) {
    if (Math.random() > 0.1) return; // only log some errors

    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

La gestione degli inutili errori "window.error in undefined: 0" dipende dall'architettura del sito, ma può provare a identificare tutte le chiamate Ajax e generare un'eccezione quando qualcosa non riesce (eventualmente restituire una traccia dello stack utilizzando stacktrace.js ).


67
So che questa è una vecchia domanda, ma suggerire di ignorare casualmente alcuni errori è una delle peggiori idee che abbia mai sentito.
jbabey,

26
@jbabey: per un piccolo sito hai ragione, ma se stai gestendo un sito di grandi dimensioni con 100.000 o milioni di utenti, non hai davvero bisogno di inondare i tuoi server (o Internet) con richieste di registrazione ridondanti. Su un sistema abbastanza grande, ogni vero errore si verificherà decine di migliaia di volte al giorno, quindi questa forma di limitazione funziona bene. L'idea è effettivamente implementata su Facebook.
Jens Roland,

1
Gli errori di registrazione in modalità debug sono probabilmente importanti quanto la limitazione dei rapporti sugli errori di produzione, quindi si può notare che è necessaria una soluzione per gestire quel valore che limita la soglia di registrazione.
frattaro,

2
@NickBull Ho invertito la progettazione di un gruppo di moduli JavaScript di Facebook nel 2011-2012; è lì che l'ho trovato.
Jens Roland,

1
@NickBull ha appena controllato i miei vecchi file, aveva ancora questi. Ho trovato questo trucco nel modulo bootloader di Facebook: if (global.logJSError) if (Math.random() < .01) logJSError('bootloader', {(è vero che quel codice non limita tutti gli errori, solo una specifica classe di errori di timeout)
Jens Roland,

7

IHMO, dovresti usare la gestione degli errori in JavaScript come in altre lingue (AFAIK: Python, Java).

Per una migliore leggibilità (e probabilmente migliori prestazioni, anche se non sono sicuro che abbia un impatto davvero grande), dovresti usare il blocco try / catch principalmente nei seguenti casi:

  • La parte del codice che desideri racchiudere è una parte fondamentale dell'intero algoritmo . Se fallisce, potrebbe:

    • creare errori nella parte successiva dei codici (ad es. perché manca un var ...)
    • fare in modo che la pagina non appaia come previsto (impatto sul contenuto o CSS)
    • rendere strani i risultati per l'utente (impatto sul comportamento del codice)
  • Sai che il codice che stai scrivendo non è compatibile con tutti i browser

  • Hai pianificato che il codice potrebbe fallire (perché non c'è altro modo per verificare che dovrebbe funzionare se ... quindi ... blocca)
  • E anche quando si desidera eseguire il debug senza disturbare l'utente finale

Alla fine, gli esperti di JavaScript possono avere altri elementi da dare.

i miei 2 centesimi alla scatola,

Saluti,

Max


1
"La parte del codice che vuoi racchiudere è una parte fondamentale dell'intero algoritmo" - potrebbe dipendere da come vuoi gestire l'errore. Se sai che non c'è modo di continuare con l'algoritmo in caso di fallimento, potrebbe essere meglio avvolgere il tutto in un tentativo / cattura perché se il tuo tentativo / cattura è (ad es.) Sepolto all'interno di cicli nidificati, sarà più che un successo nelle prestazioni . D'altra parte, se è possibile eseguire alcune azioni in caso di eccezione e continuare con l'algoritmo, sarà necessaria una configurazione try / catch più dettagliata.
nnnnnn,

5

Oltre alle altre risposte: una cosa importante è utilizzare i dati di contesto disponibili negli oggetti di errore JavaScript e nei window.onerrorparametri della funzione.

Cose come stacktrace (errorObject.stack), il nome file, il numero di riga e il numero di colonna. Ogni browser presenta alcune differenze ... quindi fai del tuo meglio per ottenere errori.

Ci possono anche essere problemi con l' oggetto console stesso . Uso una funzione window.onerror personalizzata ispirata a questa e una funzione speciale per tracciare qualsiasi oggetto errore standard ispirato da questo codice .

Un altro punto positivo è includere la versione della tua applicazione web da qualche parte vicino allo stacktrace (per copia e incolla veloci e sicure). Puoi anche mostrare gli errori in modo più aggressivo (avviso ...) in modalità di sviluppo poiché gli sviluppatori non monitoreranno costantemente la console del browser e potrebbero non vedere alcuni dei problemi.

Usa anche evita di usare throw 'My message', usa throw new Error('My message'), puoi anche avere errori personalizzati, leggi questo articolo .

Aggiungi sempre un po 'di contesto agli errori (la versione, l'id dell'oggetto, un messaggio personalizzato, ...) e assicurati anche di fare una distinzione tra errori esterni (alcuni dati esterni o circostanze hanno fatto fallire il tuo sistema) ed errori interni / assertions (il tuo sistema è incasinato), leggi " Design by contract ".

Ecco una guida .

Pensa anche a utilizzare la gestione generale degli errori come intercettori per le tue librerie e framework:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.