2013-06-14 13 views
8

Rozwijam mały pakiet Node.js, który zawiera analizator składni. Rzuca się, gdy tylko wykryje nieodwracalny problem.Przekaż błąd przyczyny wrzuconym obiekcie/Jak radzić sobie z błędami we współczesnym JavaScriptu

Używam Java od wielu lat i jestem przyzwyczajony do mas klas wyjątków.

Ale to jest JavaScript. Myślę, że to kwestia stylu. Moim zasadniczym problemem jest przekazanie przyczyny błędu w celu wychwycenia bloków. Pomyślałem o utworzeniu albo różnych klas "Error" z różnych powodów błędu, z których każdy dbał o szczegóły dotyczące każdego problemu, albo jednej klasy Error, która utrzymuje przyczynę jako właściwość.

Podam przykład postępowania oba rodzaje błędów:

catch(e) { 
    if(e instanceof FirstError) { 
    ... 
    } 
    if(e instanceof SecondError) { 
    ... 
    } 
} 

catch(err) { 
    if(err instanceof AnError) { 
    if(err.detail === 'becauseOfA') { 
     ... 
    } 
    if(err.detail === 'becauseOfB') { 
     ... 
    } 
    } 
    ... 
} 

Która z metod jest lepsza? Oba będą działać, ale nie podoba mi się pierwszy. Wiele zajęć wydaje mi się ogromnym obciążeniem.

Edit:
zgadzam się na wykorzystaniu zwrotnych (także odpowiedział here):

// One class per error type 
function(err, ast) { 
    if(err) { 
    if(err instanceof FirstError) { 
     ... 
    } 
    if(err instanceof SecondError) { 
     ... 
    } 
    } 
    ... 
} 

// One class for all errors 
function(err, ast) { 
    if(err) { 
    if(err instanceof AnError) { 
     if(err.detail === 'becauseOfA') { 
     ... 
     } 
     if(err.detail === 'becauseOfB') { 
     ... 
     } 
    } 
    ... 
    } 
} 

// No class at all 
function(err, ast) { 
    if(err) { 
    if(err.detail === 'becauseOfA') { 
     ... 
    } 
    if(err.detail === 'becauseOfB') { 
     ... 
    } 
    ... 
    } 
} 

Problem ustępuje: Jeżeli wpadnę wszystkie klasy i użyć prosty obiekt bez prototypal dziedziczenia? Muszę przekazać informacje o problemie do obsługi błędu (catch lub callback).

Chcę, aby ta funkcja była synchroniczna, ponieważ jest mała i szybka (tak, wiem, że wywołanie zwrotne nie powoduje asynchronizacji funkcji). AFAIK Node.js sam rzuca Błędy w kodzie synchronicznym (fs.readFileSync) podczas przekazywania obiektów błędów do wywołań zwrotnych w funkcjach asynchronicznych (fs.readFile).

+0

+1 za użycie '==='. Wolałbym pierwszą wersję, chociaż nigdy nie używam 'try' -'catch'es w JavaScript. – Kninnug

+0

+1 dla sprawy. Zastanawiam się również, jakie jest najlepsze podejście w js. – lukaleli

+0

Jestem zaskoczony, że pochodząc z Javy, nie chcesz używać wielu klas :) Ale czy to naprawdę tak długo: 'var ExceptionTypeA = function() {};'? – RandomSeed

Odpowiedz

1

Myślę, że najlepszym podejściem do węzła jest przepisanie modułu w stylu wywołania zwrotnego. Chociaż należy przekazać do callbacków dwa argumenty: pierwszy to błąd lub wartość pusta (jeśli operacja została pomyślnie zakończona), druga to wynik operacji (lub wartość null lub undefined, jeśli wystąpił błąd).

Niż można po prostu obsługiwać je w swoim oddzwonieniu. Możesz przekazywać błędy jako łańcuchy, a następnie tylko przypadek (błąd) do obsługi różnych sytuacji.

UPD:

Dla metod synchronizacji można używać rzuca, ale również może rzucać tylko struny, a następnie przełączać je. Jeśli chcesz typować błędy (na przykład, jeśli metoda może generować bardzo różne błędy (w kodzie Java mogą być opisane w różnych klasach)), możesz użyć obiektu wyglądającego tak: {error: 'error_name', type: 'error_type "}.

A następnie przełącz (err.type), przełącznik (err.error).

Użycie klas dla tego w JavaScript nie jest najlepszym podejściem, ponieważ po prostu tworzy obiekt z właściwościami prototypu, wskazując na obiekt konstruktora, a instaceof porównuje te wskaźniki.

+0

Dziękuję! Zrzuciłbym wszystkie klasy błędów i przekazałbym problemy do wywołania zwrotnego, prawda? Czy plik node.js nie przekazuje obiektów błędów (wystąpień błędów) do wywołań zwrotnych? Czy jest to najlepsze podejście do funkcji niezsynchronizowanej? –

Powiązane problemy