2014-09-10 8 views
7

W moim programie NodeJS analizuję plik JSON użytkownika.Jak określić "spowodowany" w błędzie JavaScript?

więc używam:

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

Problemem jest to, że jeśli plik json nie jest prawidłowo sformatowany, błąd rzucony jest tak:

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) 
... 

Ponieważ nie jest naprawdę przyjazny dla użytkownika Chciałbym rzucić Error określając pewien przyjazny dla użytkownika komunikat (jak "twój plik konfiguracyjny nie jest dobrze sformatowany"), ale chcę zachować stacktrace w celu wskazania problematycznej linii.

W świecie Java użyłem throw new Exception("My user friendly message", catchedException), aby mieć oryginalny wyjątek, który spowodował ten.

Jak to jest możliwe w świecie JS?

+0

owinąć go w 'try {} catch() {}' i utworzyć własną wiadomość. –

+0

Tak to właśnie chciałem zrobić na początku. Ale chciałem również zachować oryginalny stos, który zawiera oryginalną wiadomość wskazującą na problematyczną linię (w moim przykładzie) ... I nie mogę znaleźć "dobrego" sposobu, aby to zrobić w obsłudze błędów JS, którą widziałem do teraz w sieci ... –

+0

Rzeczywiście widzę, że moje pytanie jest duplikatem: http://stackoverflow.com/questions/17886769/how-to-chain-exceptions-in-javascript-ie-add-cause-like -in-java –

Odpowiedz

7

Co ja w końcu zrobili to:

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

A jednak ["główne źródło"] (https://www.joyent.com/developers/node/design/errors) dotyczące najlepszych praktyk wspomina, aby w ogóle nie dotykać własności "stosu". W języku java istnieje właściwość "przyczyny". Czy ludzie z Nodejs oczekują, że zostanie to ustalone? – dmansfield

+0

Lepszą odpowiedzią byłoby coś, co oblicza tylko stos, gdy zostanie odczytany. Coś jak Object.defineProperty (newErr, 'stack', {get: function() {return ??? + '\ nOdwiedziony przez: "+ err.stack}}). Ale poza tym, wydaje mi się to całkiem miłe. –

+1

Zakładam, że ostatnia linia powinna być: 'throw newErr;' – fmpdmb

-1

Użyj try/catch bloku:

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: Jeśli czujesz potrzebę błędu niestandardowego można zdefiniować własne:

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/

wiele przydatnych informacji na https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

+0

Chciałem "rzucić" coś, ponieważ jestem w kodzie biblioteki, więc chcę, aby programista, który go używa, był w stanie go złapać i wyświetlić użytkownikowi w sposób, w jaki chce ... Właściwie to chcesz zrobić coś takiego, jak przekazanie głównej przyczyny do nowego wyjątku w Javie –

+0

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

+1

Po prostu edytuj ten i zmienić e.wiadomość na twój przyjazny dla użytkownika komunikat i wyślij e –

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

Po tym pomijam linię problemu z pliku JSON wyświetlanego przez oryginalny błąd przez NodeJS ... –

+0

Zgłoszony błąd nadal będzie zawierał stos w właściwości stosu. –

+1

Nie tylko zawiera stos z linii 'nowy błąd'. Nie widzę więcej "undefined: 55},^SyntaxError: nieoczekiwany token}" część catched 'e'. –

1

Joyent wydany pakiet node.js, które można wykorzystać właśnie do tego. Nazywa się VError. I wklej przykład jak można użyć 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); 
}); 

by wydrukować następujące:

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

Proszę nie zamieszczać identycznych odpowiedzi na [wiele pytań] (http://stackoverflow.com/a/40287580). Napisz jedną dobrą odpowiedź, a następnie głosuj/oznacz, aby zamknąć pozostałe pytania jako duplikaty. Jeśli pytanie nie jest duplikatem, * dostosuj swoje odpowiedzi na pytanie. * –

Powiązane problemy