2013-11-09 17 views
14

Mam serwer Node.js, który ciągle się zawiesza, nie rejestrując żadnego komunikatu o błędzie. Czy to typowy scenariusz? Jak mogę przechwycić błąd i zalogować go, zanim się zawiesi?Awaria serwera Node.js bez komunikatu o błędzie

+1

Oprócz zalogowaniu niezłapane wyjątki, aby znaleźć przyczynę awarii, można sprawdzić, jeśli procesowi kończy się pamięć. –

+1

Czy możesz polecić sposób sprawdzenia użycia pamięci serwera? –

+0

Sposób, w jaki zrobiłem to dwa lata temu, polegał na uruchomieniu serwera węzła z powłoki i przechwytywaniu stderr. V8 w tym czasie bezceremonialnie wyjdzie i napisze komunikat o błędzie na stderr. Jednak V8 bardzo się zmieniło i nie wiem, czy ta technika zadziała. Monitorowanie pamięci procesowej może pomóc w przypadku awarii po długim czasie. –

Odpowiedz

28

Dobrym początkiem byłoby ustawienie, szczególnie w produkcji, przed ustawieniem detektora dla serwera, procedura obsługi wyjątków rejestrujących szczegóły. Spójrz na here:

process.on('uncaughtException', function (exception) { 
    console.log(exception); // to see your exception details in the console 
    // if you are on production, maybe you can send the exception details to your 
    // email as well ? 
}); 

Jeśli używasz Express.js, spojrzeć na here umieć zobaczyć pełny stos swój błąd (i ostatecznie znów wysłać go do wiadomości e-mail, jeśli są na produkcja). W takim przypadku, należy poinformować go, aby dać Ci wszystkie szczegóły przed instancji słuchacza:

var express = require('express'); 
// ... 
var app = express(); 
// ... 
app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
// then, set the listener and do your stuff... 
+6

Oprogramowanie pośredniczące "errorHandler' nie jest już dostarczane z plikiem ekspresowym. Możesz zainstalować go przez puszczenie 'npm install errorhandler' - zobacz szczegóły tutaj https://github.com/expressjs/errorhandler – muchweb

4

Aby zakończyć odpowiedź @matteofigus, można również listen for unhandled promise rejections.

process.on('unhandledRejection', (reason, p) => { 
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); 
    // application specific logging, throwing an error, or other logic here 
}); 

somePromise.then((res) => { 
    return reportToUser(JSON.pasre(res)); // note the typo (`pasre`) 
}); // no `.catch` or `.then` 
0

Można używać middleware o nazwie 'ErrorHandler' & z 'rejestratora' (log4js-NPM-pakietu) można przechowywać dziennik dla wszystkich wyjątków błędach. Oto kod dla Errorhandler:

// Middleware: Catch-All Error Handler. Abyśmy rejestrowali błędy, ale nie ujawniamy szczegółów błędów wewnętrznych klientowi.

app.use(errorHandler); 

function errorHandler(err, req, res, next) { 

// XHR Request? 
if (req.xhr) { 
    logger.error(err); 
    res.status(500).send({ error: 'Internal Error Occured.' }); 
    return; 
} 

// Not a XHR Request. 
logger.error(err); 
res.status(500); 
res.render('framework/error', { error: "Internal Server Error." }); 

// Note: No need to call next() as the buck stops here. 
return; 
} 
0

v6.11.0 Node, Windows 10.

Próbowałem inne sugestie tutaj bezskutecznie - aplikacja po prostu przestaje, brak błędów nawet przy użyciu

process.on('uncaughtException',...) 
process.on('unhandledRejection',....) 

Wreszcie gąsienicowego wyjścia/katastrofie w dół rekurencyjne wywołanie funkcji. Poniższy kod demonstruje problem;

"use strict" ; 

process.on('uncaughtException', function (exception) { 
    console.log(exception); 
}); 

var count = 0 ; 
function recursiveFunction(){ 
    console.log(count++); 
    recursiveFunction(); 
} 
recursiveFunction() ; 

To będzie działać tak daleko, a następnie po prostu przestać. Try/Catch też nie działa - wypróbowany jak wyżej;

function recursiveFunction(){ 
    console.log(count++); 
    try{ 
     recursiveFunction(); 
    } 
    catch(e){ 
     console.log("recursion error"); 
    } 
} 

Znów nic - po prostu się zatrzymuje.

Obejście problemu (bez konieczności przeprojektowania kodu) polega na użyciu metody setImmediate (w celu uniknięcia procesu rekursji);

function recursiveFunction(){ 
    console.log(count++); 
    setImmediate(recursiveFunction); 
} 

(I ostatecznie Ctrl-c'd to, żeby go zatrzymać.)

zgłaszane na node github issues

Powiązane problemy