app.get('/test', (req, res, next) => {
const err = new Error('Test');
next(err);
});
express will log the error and stacktrace to the console. Is there a way that I can suppress the logging?
If you put an error handler middleware in your Express implementation to handle the next(err) call like this:
// defined as the last route
app.use(function (err, req, res, next) {
res.status(500).send('Something broke!')
});
then, Express won't log any error and you can control what response is sent for the error.
I'd suggest reading this page on Express error handling: https://expressjs.com/en/guide/error-handling.html.
If you look in the express code where this logging comes from, it comes from this code:
function logerror(err) {
/* istanbul ignore next */
if (this.get('env') !== 'test') console.error(err.stack || err.toString());
}
which curiously enough shows that if you do this:
app.set('env', 'test');
or you set NODE_ENV=test in the environment before launching your server, then it will skip the error logging too. But, it's much better to just control things with your own error handler as I show about where you can also control what type of response is sent.
Related
app.use(function (req, res, next) {
throw new Error('critical');
})
makes Express server to catch a critical error and output it, while I want it to crash.
Adding an error handler doesn't replace the default handler.
How can Express error handling be disabled for critical errors?
If you want your server to crash in the event of a critical error, you can define an error-handling middleware. This is done by defining a function with 4 parameters, the first being the error. This will be called when an error is thrown. You can check the error and determine if it's critical, and if so, call process.exit.
const app = require('express')()
app.use('/', (req, res) => {
throw new Error('critical')
})
app.use((err, req, res, next) => {
if (err.message === 'critical') {
process.exit(1)
} else {
// carry on listening
}
})
I'm somewhat new to NodeJS, and current I used Express and Request ( https://github.com/request/request ) to forward my app request to REST api server, current my code shown below:
app.use('/rest/*', function(req, res) {
req.pipe(request('http://ipaddress/api')).pipe(res);
});
this code works when the REST API server is OK, but if the rest api server goes down, my nodejs app also goes down, because request stream will fail and the error is not caught by my app.
I checked the Request github page, it provides one way to handle the stream error, like
app.use('/rest/*', function(req, res) {
req.pipe(request('http://ipaddress/api').on('error', function(err) {
console.log(err);
})).pipe(res);
});
this can only log the error and prevent my NodeJS app crashing, but I want to change the response when error occurred so that the changed response can be piped to final one, for example, what I want to do in pseudocode:
app.use('/rest/*', function(req, res) {
req.pipe(request('http://ipaddress/api').on('error', function(err) {
console.log(err);
// what I want to do in pseudocode
response.statusCode = 500;
response.json = {
reason: err.errno
};
})).pipe(res);
});
Are there any ways to solve my problems? Thanks for any ideas!
Untested but could you pass the error back to middleware to handle the reponse?
app.use('/rest/*', function(req, res, next) {
req.pipe(request('http://ipaddress/api').on('error', function(err) {
return next(err)
})).pipe(res);
});
Handled like so
// Exception handling
app.use(function (error, req, res, next) {
console.log(error);
res.status(500).send(JSON.stringify(error));
next();
});
In the following node.js server code, since "ABCDE" is not a defined a variable, error is thrown when '/upload' is requested. What confused me is that, the error stack trace printed on the console at server side is sent back to the client, which is unsafe.
How can I prevent that, other than catch that error?
var express = require('express');
var app = express();
app.use(function (err, req, res, next) {
res.send(500, 'Something broke!');
});
app.post('/upload', function (req, res) {
console.log(ABCDE);
});
app.listen(3000);
You already have the answer in your question. You need error-handling middleware (app.use a function with an arity of 4) to handle the error.
You just need to add the error-handling middleware after the router. Your example puts the the error handler above the the router.
Either move the app.use(function (err, req, res, next)) to the bottom of your code or insert
app.use(app.router);
above the error handler.
Refer to the documentation for more information about error handlers.
A common pattern in my Express app is to include the following in all my routes:
//...code which could result in an err
if (!err) return res.send(200);
console.log(err); // Would prefer to omit this line
res.send(500);
Right now, I need to write console.log(err) in all my routes. I'd prefer to just automatically log the err variable every time a 500 is sent. Is there any way to hook into Express and automatically log the call stack and/or err for all 500 responses?
From your explanation, you seem to be including error handling in all your routes.
You probably should create a global interceptor error handler which can perform the logging for you and still be the base error handler if you have a 500 error type.
//if your express var is app
var errorHandler = function(err, req, res, next){
console.log(err.stack);
res.send(500);
// or you could call res.render('error'); if you have a view for that.
};
app.use(app.router); // this has to come before your interceptors
app.use(notFound); // your page not found interceptor
app.use(errorHandler);
I'm developing an express app.
I currently have the following in my server.js
process.on('uncaughtException', function (err) {
console.log( "UNCAUGHT EXCEPTION " );
console.log( "[Inside 'uncaughtException' event] " + err.stack || err.message );
});
Which stops the server crashing every time there's an error, however, it just sits there...
is it possible to instead of console.log, to send a 500 error page with the error details?
I don't think you can from within the uncaughtException do a response since that could happen even when there is no request occurring.
Express itself provides a way to handle errors within routes, like so:
app.error(function(err, req, res, next){
//check error information and respond accordingly
});
Per ExpressJS Error Handling, add app.use(function(err, req, res, next){ // your logic }); below your other app.use statements.
Example:
app.use(function(err, req, res, next){
console.log(err.stack);
// additional logic, like emailing OPS staff w/ stack trace
});