2012-11-10 12 views
11

Mam aplikację w Node.js i Express. Muszę napisać dla niego testy. Mam problem z obsługą błędów aplikacji Express. Znalazłem to How do I catch node.js/express server errors like EADDRINUSE?, ale to nie działa dla mnie, nie wiem dlaczego. Chcę obsługiwać błędy, które mogły wystąpić podczas wykonywania funkcji expressApp.listen() (EADDRINUSE, EACCES itd.).Błędy błędów uruchamiania aplikacji Node.js Express

express = require('express') 
listener = express() 

#doesn't work for me 
listener.on('uncaughtException', (err) -> 
    #do something 
) 

#doesn't work too 
listener.on("error", (err) -> 
    #do something 
) 

#this works, but it caughts all errors in process, I want only in listener 
process.on('uncaughtException', (err) -> 
    #do something 
) 

listener.listen(80) #for example 80 to get error 

Wszelkie pomysły?

+0

listener.on 'błąd' '...' powinno działać. Czy po prostu robi normalne śledzenie stosu i awarię, nawet jeśli ta linia jest tam? – loganfsmyth

+0

Tak, jeśli zrobię to "listener.listen (80)" , drukuje to śledzenie i awarie stosu.Nawet z 'listener.on' error ', ...' Może błąd w tym przypadku nie jest błędem Express i dlatego nie obsługuje. Ale to tylko założenie. –

Odpowiedz

20

Po pierwsze, expressJS nie rzuca zdarzenie uncaughtException, proces to robi, więc nic dziwnego, że twój kod nie działa.

Dlatego użyj: process.on('uncaughtException',handler) zamiast.

Następnie expressJS już dostarcza standardowe sposoby obsługi błędów, który ma korzystać z funkcji middleware dostarcza do tego celu, na przykład:

app.configure(function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

Funkcja ta zwraca komunikat o błędzie do klienta, z opcjonalnym stacktrace i jest udokumentowany pod numerem connectJS errorHandler.

(Zauważ, że errorHandler jest faktycznie częścią connectJS i jest wystawiony tylko przez expressJS.)

Jeśli zachowanie istniejącego errorHandler zapewnia nie jest wystarczający dla Twoich potrzeb, jej źródło znajduje się na connectJS's errorHandler middleware i mogą być łatwo modyfikowane w zależności od potrzeb.

Oczywiście, zamiast modyfikacji tej funkcji bezpośrednio, „poprawny” sposób to zrobić, aby stworzyć swój własny errorHandler, korzystając z wersji connectJS jako punkt wyjścia, na przykład:

var myErrorHandler = function(err, req, res, next){ 
    ... 
    // note, using the typical middleware pattern, we'd call next() here, but 
    // since this handler is a "provider", i.e. it terminates the request, we 
    // do not. 
}; 

I zainstalować to w expressJS jak:

app.configure(function(){ 
    app.use(myErrorHandler); 
}); 

Zobacz Just Connect it, Already o wyjaśnienie idei connectJS dnia filter i provider middleware i How To Write Middleware for Connect/Express za dobrze napisany poradnik.

Można również znaleźć te przydatne:

Wreszcie doskonałym źródłem informacji na temat testowania expressJS można znaleźć w its own tests.

+0

+1, bardzo dobra, wyczerpująca odpowiedź! – Menztrual

+0

Dzięki za tak szczegółowe wyjaśnienie, przydałby się i tak. Nie muszę obsługiwać błędów podczas przetwarzania żądania internetowego. Potrzebuję podczas tworzenia serwera i wywołania app.listen (...). Teraz rozumiem, że tutaj potrzebna jest obsługa błędów Node.js, a nie oprogramowanie pośrednie w Express. process.on ("uncaughtException", handler) jest w moim przypadku akceptowalny. –

+0

@Piane_Ramso, następnie tak, dodanie własnych procedur obsługi zdarzeń do 'process.on ('uncaughtException')' jest zdecydowanie najlepszą drogą. Jeśli jesteś ciekawy, kod źródłowy przetwarzający "nieprzechwycone" wyjątki znajduje się w (lub w pobliżu) wierszu # 1739 w [node.cc] (https://github.com/joyent/node/blob/master/src/ node.cc) –

57

To powinno załatwić sprawę:

listener.listen(80).on('error', function(err) { }); 

Co listener.listen rzeczywiście robi jest stworzenie serwera HTTP i zadzwoń słuchać na nim:

app.listen = function(){ 
    var server = http.createServer(this); 
    return server.listen.apply(server, arguments); 
}; 
+10

To niewiarygodne, że jest to najprostsza i najbardziej poprawna odpowiedź, i że nie ma w niej żadnych przebojów! Sztuką jest zrozumienie, że obiekt webServer jest zwracany przez app.listen. Używam tego: '' 'app.listen (80, function() { console.log (" sukces "); }). On (" błąd ", funkcja (err) { if (err.errno === 'EADDRINUSE') { console.log ('port busy'); } else { console.log (err); } }); '' ' –

+0

Nie rozumiem, że twój kod robi. jeśli wywołujesz węzeł app.listen już działa pod http.createServer pod maską, o której myślałem lub czy w zasadzie nadpisujesz natywną metodę app.listen() i nadpisujesz ją swoim własnym kodem? – PositiveGuy

+0

Pierwsza linia kodu jest tym, co powinno być używane, wszystko inne jest wyjaśnieniem, dlaczego to działa. –

Powiązane problemy