Zasady obsługi błędów dla węzła.js + Express.aplikacje js?
Wygląda na to, że raportowanie/obsługa błędów odbywa się inaczej w węźle.js + Express.aplikacje js w porównaniu do innych frameworków. Czy mam rację, rozumiejąc, że działa to w następujący sposób?
A) Wykryj błędy , odbierając je jako parametry do funkcji wywołania zwrotnego. Na przykład:
doSomethingAndRunCallback(function(err) {
if(err) { … }
});
B) Zgłoś błędy w MIDDLEWARE, wywołując next (err). Przykład:
handleRequest(req, res, next) {
// An error occurs…
next(err);
}
C) Raport błędy w trasach poprzez wyrzucenie błędu. Przykład:
app.get('/home', function(req, res) {
// An error occurs
throw err;
});
D) Obsługa błędów poprzez konfigurację własnego programu obsługi błędów za pomocą aplikacji.error() lub użyć generic Connect Error handler. Przykład:
app.error(function(err, req, res, next) {
console.error(err);
res.send('Fail Whale, yo.');
});
Czy te cztery zasady są podstawą do obsługi/raportowania błędów w węźle.js + Express.aplikacje js?
3 answers
Obsługa błędów w węźle.js jest na ogół formatu A). Większość wywołań zwrotnych zwraca obiekt błędu jako pierwszy argument or null
.
Express.js używa middleware, a składnia middleware używa B) i E) (wymienionych poniżej).
C) to zła praktyka.app.get('/home', function(req, res) {
// An error occurs
throw err;
});
Możesz łatwo przepisać powyższe jako
app.get('/home', function(req, res, next) {
// An error occurs
next(err);
});
Składnia Middleware jest ważna w zapytaniu get
.
Jak dla D)
(07:26:37 PM) tjholowaychuk: ok.błąd jest usuwany w 3.x
TJ właśnie potwierdził, że app.error
jest przestarzałe na rzecz E
E)
app.use(function(err, req, res, next) {
// Only handle `next(err)` calls
});
Każda warstwa pośrednicząca o długości 4 (4 argumenty) jest uważana za warstwę pośredniczącą błędów. Po wywołaniu next(err)
connect goes i wywołaniu oprogramowania pośredniczącego opartego na błędach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-04 10:28:32
Ludzie w Joyent opublikowali naprawdę wnikliwy dokument najlepszych praktyk na ten temat. Artykuł obowiązkowy do przeczytania dla każdego węzła.js developer.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-12 15:42:10
Dlaczego pierwszy parametr?
Ze względu na asynchroniczny charakter węzła.js, wzorzec first-parameter-as-err stał się dobrze ugruntowaną konwencją dla węzła userland.obsługa błędów js . Dzieje się tak dlatego, że asynchroniczne:
try {
setTimeout(function() {
throw 'something broke' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Więc zamiast pierwszego argumentu wywołania zwrotnego jest prawie jedynym sensownym sposobem przekazywania błędów asynchronicznie, innym niż tylko rzucanie ich.
To spowoduje unhandled exception
, które, tak jak to dźwięki, oznacza, że nic nie zostało zrobione, aby uzyskać aplikację z jej zdezorientowanego stanu.
Wyjątki, dlaczego istnieją
Warto jednak zauważyć, że praktycznie cała część węzła.js są emiterami zdarzeń, a rzucanie wyjątków jest zdarzeniem niskiego poziomu, które może być obsługiwane jak wszystkie zdarzenia: {]}
//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
To może-ale-nie powinno być doprowadzone do skrajności złapać wszystkie błędy i złożyć wniosek, który będzie bardzo starał się nigdy nie zawiesić. To jest okropny pomysł w prawie każdym przypadku użycia, ponieważ pozostawi programistę bez żadnego pojęcia o tym, co dzieje się w stanie aplikacji i jest analogiczny do owijania main w try-catch.
Domeny-grupowanie zdarzeń logicznie
W ramach radzenia sobie z problemem WYJĄTKÓW powodujących upadek aplikacji, domeny pozwalają programistom na wzięcie np. Express.aplikacji js, a także próby sensownego zamykania połączeń w przypadku katastroficznego porażka.
ES6
Prawdopodobnie wspominamy, że to się zmieni ponownie, ponieważ ES6 pozwala wzorzec generatora na tworzenie asynchronicznych zdarzeń, które nadal są chwytalne za pomocą bloków try / catch.
Koa (napisane przez TJ Holowaychuck, tego samego autora Express.js). Używa instrukcji ES6 yield
do tworzenia bloków, które, choć wydają się prawie synchroniczne, są obsługiwane w zwykły asynchroniczny sposób węzła:
app.use(function *(next) {
try {
yield next;
}
catch (err) {
this.status = err.status || 500;
this.body = err.message;
this.app.emit('error', err, this);
}
});
app.use(function *(next) {
throw new Error('some error');
})
Ten przykład był bezwstydnie skradziony z tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-04 10:35:42