2014-12-15 9 views
13

Właśnie zacząłem wypróbowywać SailsJS kilka dni temu.
Zdałem sobie sprawę, że węzeł jest zakończona, gdy mam nieprzechwycony wyjątek.
Mam listę kontrolerów i każdy z nich wywołuje określony plik JS usługi (Zawiera logiki i wywołania DB) w usługach /.
Czy mogę napisać globalną procedurę obsługi błędów dla wszystkich usług, aby każdy rodzaj błędu występujący w tych usługach był obsługiwany przez nią, a odpowiednia odpowiedź błędu musi zostać przekazana do strony front-end.Najlepsze praktyki dotyczące obsługi wyjątków w SailsJS

Próbowałem za pomocą process.on („uncaughtexception”) lub niektóre z podstawowych wyjątkami ale to musi być dodana do każdego sposobu użytkowania.

Również mogę mieć jeden punkt wspólny dla wszystkich połączeń wykonanych usług od klienta do serwera, przez który wszystko io.socket.post() i io..socket.get() przechodzi

Uprzejmie jakiejkolwiek wskaźnik/artykuł, który pokaże mi wspólne najlepsze praktyki dotyczące obsługi niezatrzymanych wyjątków w SailsJS i używania krótszego kodu zamiast pisania redundantnego kodu we wszystkich usługach.

+0

Naprawdę dobre pytanie. Nigdy nie myślałem o tym wcześniej, ale zasady to kod, który jest wykonywany przed wywołaniem akcji kontrolera. Możesz spróbować owijać logikę kontrolera w bloku catch catch za pomocą zasady i stosując tę ​​zasadę jako domyślną dla wszystkich działań kontrolera. Nie próbowałem tego i to była tylko przypadkowa myśl, która przyszła mi do głowy. Daj znać czy działa. Mogę spróbować później –

+0

To nie jest odpowiedź * jeszcze *, ale miej oko na [strefy] (http://strongloop.com/strongblog/announcing-zones-for-node-js/) - między innymi rzeczy rozwiązuje problem obsługi błędów w nodejs. –

Odpowiedz

4

Najlepsze praktyki korzysta Domains w kontrolerze. Spowoduje to obsługę wyjątków w kodzie asynchronicznym i jest stosunkowo prosta.

można użyć coś jak trycatch aby uprościć trochę, ale domena oparta wyjątki będą najbardziej skuteczne. Zapewni to, że wyjątki nie spowodują awarii aplikacji. Po prostu utwórz nową domenę w kontrolerze i przeprowadź swoje metody kontrolera wewnątrz tej domeny.

Sailsjs jest na podstawie wyraźnej można wykorzystać połączyć middleware, można bezproblemowo utworzyć nową domenę z middleware. Istnieje coś takiego jak express-domain-middleware. To może być najbardziej estetyczna opcja i najwygodniejsza.

Aktualizacja: Jak wspomina Benjamin Gruenbaum planowane są Domains by stać się przestarzałe w v1 węzła. Być może powinieneś przeczytać Joyents Error Handling Best Practices. Jest agnostyczny w stosunku do używanej struktury.

Additonally można nadal korzystać z domen, podczas gdy nie jest to sposób na globalne błędy uchwyt w node.js inaczej. Po wycofaniu możesz stosunkowo łatwo usunąć zależność od Domen. Powiedział, że najlepiej jest nie polegać wyłącznie na domenach.

Strongloop dostarcza również bibliotekę inspirowany domen zwanych Zone. Jest to również opcja.

+1

Domeny będą prawdopodobnie przestarzałe w najbliższej przyszłości. https://github.com/iojs/io.js/issues/66 –

+0

Zdefiniuj "najbliższą przyszłość", wersja v0.11 nie ma nawet ustawionej daty wydania, a wersja v0.12 nie będzie widoczna dla co najmniej kolejnego roku, i to jest optymistyczne. AFAIK v1 nie jest jeszcze rozwijany, a do tej pory tylko myślał. Wspomniano nawet, że domeny prawdopodobnie zostaną przeniesione do pakietu (z rdzenia), aby zachować kompatybilność wsteczną. Jeśli użyjesz sugerowanego oprogramowania pośredniego, to z łatwością zastąpisz obsługę wyjątków. – tsturzl

+0

W najbliższej przyszłości jest to ~ miesiąc. Węzeł został niedawno rozwidlony w pliku io.js, a większość głównych współtwórców migrowała (z powodu cyklu wydawania). Powiedziałem, że przestarzałe, nie usunięte. –

0

nie próbowałem tego, ale uważam, że powinniśmy być w stanie ustawić catch-all obsługi wyjątku w bootstrap.js użyciu process.on('uncaughtexception').

Osobiście używam obietnic za pośrednictwem biblioteki bluebird i umieszczam instrukcję przechwytywania, która przekazuje wszystkie błędy do globalnej funkcji obsługi błędów.

+0

Nie spadam, ale jest to bardzo zła praktyka, ponieważ twoja aplikacja wysyła gdzieś nieobsługiwany wyjątek. Jest to luźna obsługa błędów i za każdym razem, gdy ktoś o tym mówi, musisz mu towarzyszyć fakt, że proces powinien zostać zatrzymany i uruchomiony ponownie, a Ty nie powinieneś ** próbować kontynuować tego, co robisz (wgrywanie, pisanie pliku , db komunikacja, itp.). Musisz zatrzymać wszystko i zrestartować proces węzła. –

+0

Zakładam, że odnosisz się do nie obiecywanego rozwiązania, które naprawdę powinienem poprzedzić "hej, możesz to zrobić, ale nie rób tego". – CaseyWebb

+0

Niezupełnie, a ja nie chciałem zejść na ciebie - ale pisanie kodu z niezłomnymi wyjątkami to po prostu zła praktyka i łapanie go na "szczycie" aplikacji, tak jak to jest po prostu leniwe. Większość serwerów nie wymaga ponownego uruchamiania procesu serwera w takich sytuacjach. Węzeł ma. Jeśli przechwycisz wyjątek i nie uruchomisz ponownie procesu, węzeł może utknąć w "nieznanym stanie" (jest to sposób, w jaki docs to słowo, jeśli dobrze pamiętam). –

1

Jest w porządku, aby pozwolić na błąd instancji węzła z powodu błędu programowania, w przeciwnym razie może kontynuować niespójną logikę biznesową. W środowisku produkcyjnym serwer może zostać zrestartowany po awarii, to zresetuje swój stan i będzie dostępny, jeśli błąd nie będzie częsty. A w tym wszystkim bardzo ważne jest, aby wszystko rejestrować. Dotyczy to większości konfiguracji Node, w tym SailsJS.

Poniższa metoda może być wzięty:

  1. Użyj Logger: dedykowany rejestrator powinien być dostępny dla komponentów serwerowych. Powinien być podłączony do usługi, która powiadamia programistę (e-mail?) O bardzo poważnych błędach.
  2. Propagowanie na żądanie błędów do końca: Ostrożnie przesyłaj błędy z dowolnego kroku przetwarzania żądania. W konfiguracji oprogramowania ExperssJs/ConnectJs/middleware można użyć kodu next(err), aby przekazać błąd do łańcucha middleware ware. Błąd przechwytywania middleware na końcu łańcucha otrzyma ten błąd, zarejestruje go w pełnym zakresie i wyśle ​​stan 500 z powrotem. Możesz użyć Domains lub Zones lub Promises lub async lub cokolwiek chcesz przetwarzać żądania i wychwytywać błędy.
  3. Wyłączenie w dniu process.on('uncaughtexception'): Zaloguj się do pliku erorr, wykonaj niezbędne czynności czyszczące i ponownie wygeneruj ten sam błąd, aby zamknąć proces.
  4. Użytkownik PM2/Forever lub Upstart/init.d na Linuksie: Teraz, gdy proces zostanie zamknięty z powodu złego wyjątku, narzędzia te uruchomią go ponownie i prześledzą, jak wiele serwerów czasu uległo awarii. Jeśli serwer zbyt często się zawiesza, dobrze jest go zatrzymać i podjąć natychmiastowe działanie.
+1

Upstart/init.d stanowiłoby doskonałe rozszerzenie czwartej rekomendacji. Jak zawsze, nie można ponownie uruchomić aplikacji, jeśli nastąpi nieoczekiwane ponowne uruchomienie serwera. PM2 oferuje rozwiązanie tego problemu, jednak PM2 wymaga, aby węzeł v0.11 działał efektywnie i może mieć nieoczekiwane zachowanie w wersji v0.10 lub niższej, ponieważ bazuje na "eksperymentalnych" modułach podstawowych. – tsturzl

+0

@tsturzl Dzięki. Zaktualizowano w odpowiedzi. –