2014-09-10 17 views
7

Nel mio programma NodeJS, analizzo alcuni file JSON dell'utente.Come specificare un "causato da" in un errore JavaScript?

Quindi io uso:

this.config = JSON.parse(fs.readFileSync(path)); 

Il problema è che se il file JSON non è formattato correttamente, l'errore gettato è come:

undefined:55 
      }, 
      ^
SyntaxError: Unexpected token } 
    at Object.parse (native) 
    at new MyApp (/path/to/docker/lib/node_modules/myApp/lib/my-app.js:30:28) 
... 

Poiché non è davvero facile da usare Vorrei lanciare un Error specificando un messaggio user friendly (come "il tuo file di configurazione non è ben formato") ma voglio mantenere lo stacktrace per puntare alla linea problematica.

Nel mondo Java ho utilizzato throw new Exception("My user friendly message", catchedException) per ottenere l'eccezione originale che ha causato quello.

Com'è possibile nel mondo JS?

+0

avvolgerla in 'try {} catch() {}' e creare il proprio messaggio. –

+0

Sì, questo è come volevo fare all'inizio. Ma volevo mantenere anche lo stack originale, che contiene il messaggio originale che punta alla linea problematica (nel mio esempio) ... E non riesco a trovare un modo "buono" per farlo nella gestione degli errori JS che ho visto fino a ora sul web ... –

+0

In realtà vedo che la mia domanda è un duplicato di: http://stackoverflow.com/questions/17886769/how-to-chain-exceptions-in-javascript-ie-add-cause-like -in-java –

risposta

7

Quello che ho finalmente fatto è:

try { 
    this.config = JSON.parse(fs.readFileSync(path)); 
} catch(err) { 
    var newErr = new Error('Problem while reading the JSON file'); 
    newErr.stack += '\nCaused by: '+err.stack; 
    throw newErr; 
} 
+0

Eppure la ["fonte primaria"] (https://www.joyent.com/developers/node/design/errors) riguardante le best practice menziona di non toccare affatto la proprietà "stack". In Java c'è una proprietà "causa". Le persone di nodejs si aspettano che sia impostato? – dmansfield

+0

Una risposta migliore sarebbe qualcosa che calcola lo stack solo quando viene letto. Qualcosa come Object.defineProperty (newErr, 'stack', {get: function() {return ??? + '\ nCausa da:' + err.stack}}). Ma a parte questo, mi sembra abbastanza carino. –

+1

Presumo che l'ultima riga dovrebbe essere: 'throw newErr;' – fmpdmb

-1

Utilizzare un try/catch blocco:

try { 
    this.config = JSON.parse("}}junkJSON}"); 
    //...etc 
} 
catch (e) { 
    //console.log(e.message);//the original error message 
    e.message = "Your config file is not well formatted.";//replace with new custom message 
    console.error(e);//raise the exception in the console 
    //or re-throw it without catching 
    throw e; 
} 

http://jsfiddle.net/0ogf1jxs/5/

UPDATE: Se si sente veramente la necessità di un errore personalizzato è possibile definire il proprio:

function BadConfig(message) { 
    this.message = message; 
    this.name = "BadConfig"; 
} 
BadConfig.prototype = new Error(); 
BadConfig.prototype.constructor = BadConfig; 

try { 
    this.config = JSON.parse("}}badJson}"); 
} catch(e) { 
    throw new BadConfig("Your JSON is wack!"); 
} 

http://jsfiddle.net/kL394boo/

Un sacco di informazioni utili a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

+0

Volevo "lanciare" qualcosa perché sono nel codice della libreria, quindi voglio che lo sviluppatore che lo usa sia in grado di catturarlo e visualizzarlo all'utente nel modo che vuole ... In realtà io vuoi fare qualcosa come passare la causa principale ad una nuova eccezione in Java –

+0

Vedi: http://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript – Moob

+1

Basta modificare questo e cambia e.messaggio al messaggio user-friendly e gettare e –

-1
try { 
    this.config = JSON.parse(fs.readFileSync(path)); 
} catch (e) { 
    throw new Error("User friendly message"); 
} 
+0

Con quello ho completamente perso la linea del problema dal file JSON visualizzato dall'errore originale di NodeJS ... –

+0

L'errore generato conterrà ancora il impilare nella proprietà dello stack. –

+1

No, contiene solo lo stack dalla riga 'new Error'. Non riesco a vedere più la parte "indefinita: 55},^SyntaxError: Unexpected token}" del 'e' preso. –

1

Joyent rilasciato un pacchetto Node.js che può essere utilizzato esattamente per questo. Si chiama VError. Incollo un esempio di come si può usare il pacakge:

var fs = require('fs'); 
var filename = '/nonexistent'; 
fs.stat(filename, function (err1) { 
    var err2 = new VError(err1, 'stat "%s"', filename); 
    console.error(err2.message); 
}); 

sarebbe stampare il seguente:

stat "/nonexistent": ENOENT, stat '/nonexistent' 
+0

Si prega di non pubblicare risposte identiche a [domande multiple] (http://stackoverflow.com/a/40287580). Pubblica una buona risposta, quindi vota/contrassegna per chiudere le altre domande come duplicati. Se la domanda non è un duplicato, * adatta le tue risposte alla domanda. * –

Problemi correlati