How to to create a custom logger in Express? - node.js

During an exercise in school we have been tasked with making custom middleware in Express:
This might be tricky. Make it so that your custom logging middleware
also logs out the eventual response status code. For example, after a
successful GET request to / you should see:
GET / 200
I tried this:
app.use(function(req, res, next) {
console.log(chalk.green(req.method, req.url, res.statusCode));
next();
});
It appears to work but then I noticed upon trying a uri which doesn't exist I still get:
GET /foo 200
Does this mean the request i.e. GET, is working but has nothing to do if the resource is there?
Also how would I implement error handling, in this instance I tried:
app.use(function(err, req, res, next) {
if (err) {
console.log(err);
} else {
console.log(chalk.green(req.method, req.url, res.statusCode));
}
next();
});
But that didn't work at all!
Thanks in advance!

app.use(function(req, res, next) {
if (res.headersSent) {
console.log(chalk.green(req.method, req.url, res.statusCode));
} else {
res.on('finish', function() {
console.log(chalk.green(req.method, req.url, res.statusCode));
})
}
next();
});

Related

Express.use with empty path

I got some code from a tutorial where express is used to make a NodeJS Proxy, they eventually use express.use with an empty string for the path. I can't find what the empty string will do is it the same as '/'?
The code looks like this :
app.use('', (req, res, next) => {
if(req.headers.authorization.includes('Bearer')){
next();
} else {
res.sendStatus(403);
}
})
It is not the same as /. It means that middleware will be used every time a request hits your server.
You can remove it for brevity.
app.use((req, res, next) => {
if(req.headers.authorization.includes('Bearer')){
next();
} else {
res.sendStatus(403);
}
});

How to intercept each and every req in express framework

I am looking to check user is authenticated or not before they browse something for that I have written this code.
router.use(function (req, res, next) {
console.log(req);
if(req.isAuthenticated()){
console.log("if......");
return next();
}else{
if (req.url === '/users/login' || req.url === '/users/register'){
console.log("if......2");
return next();
}else{
if (req.url === '/'){
console.log("if......3");
res.redirect('/users/register');
}else{
res.redirect('/users/login');
}
}
}
});
Now I have two questions to clear.
Is this the standard way to do this? No, please let me know how to achieve.
whenever I browse localhost:3000 my req.url = /user/login I am surprised with that too. I don't know how its even possible.
But may be cache or something not sure to clear this I must inform, Before that I had code some thing like below which was meant to intercept or validate user when he hits localhost:3000 but now I have commented that entire code.
// Get Homepage
router.get('/'/*, ensureAuthenticated*/, function(req,res){
res.render('index');
});
/*function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
}else{
res.redirect('/users/login');
}
}
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});*/
middleware come in handy here.
define your middleware like
module.exports.isAuthenticated=function(req,res,next){
if(req.isAuthenticated){
return next();
}
next(error('user is not authorized'));
}
then in your route file
route.get('/home',auth.isAutheticated,goToHome);

Is there a way to make ExpressJS log runtime errors?

I recently ran into an issue where an express route of mine was hanging, and it took me forever to finally figure out that I had a typo in one of my function calls, so it was trying to call a function that did not exist.
For example:
router.get('/example', function(req, res) {
UserService.nonExistentFunction();
res.status(200).send();
});
To me this feels like it should have been something that stuck out like a sore thumb, in the form of a runtime exception in my log. However, the server did nothing, the request just hung silently with no hints as to what went wrong.
Is there a better way to catch these dummy-type errors?
You can define your own error handler in Express.http://expressjs.com/en/guide/error-handling.html
Depends on your perferences, you can log the error in the console or to a file. In my application, I am doing something like this,
import debug = require('debug');
var app = module.exports = express();
var errorLogger = debug('error');
// Error handling
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);
// Handle 404
app.use(function(req, res, next) {
res.status(404).send('Sorry cant find that!');
});
function logErrors(err, req, res, next) {
errorLogger(err.stack);
next(err);
}
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
res.status(500).send({ error: 'Something failed!', status: 500 });
} else {
next(err);
}
}
function errorHandler(err, req, res, next) {
res.status(500);
res.render('error', { error: err, status: 500 });
}

How do I shut down my process after using Raygun's express-handler?

I'm building an app with NodeJS and Express and have recently incorporated error handling with Raygun.
Raygun provides an error handler specifically for use with Express, but it must be the last piece of middleware to run. Right now I have:
//Log the domain id, req, and error to the console
app.use(function errorHandler(err, req, res, next) {
console.log('error on request %d %s %s: %s', process.domain.id, req.method, req.url, err)
next(err)
})
//Log the error to Raygun
//!Must be last piece of middleware to be defined
app.use(raygunClient.expressHandler);
But the problem is that the server continues to run, potentially leaving the app in an unknown state. I'd like to do a graceful server shutdown, but if I add
//Shuts down the process
app.use(function errorHandler(err, req, res, next) {
process.exit()
})
then Raygun's express-handler doesn't work.
What do?
You can define custom raygunClient.expressHandler, much like the one defined in the library.
app.use(function errorHandler(err, req, res, next) {
console.log('error on request %d %s %s: %s', process.domain.id, req.method, req.url, err)
next(err)
})
app.use(function (err, req, res, next) {
raygunClient.send(err, {}, function (response) {
//all done
process.exit(1);
}, req);
next(err);
});
Now you also have the ability to send customData as 2nd argument and tags as 5th argument which was not possible with the defaul error handler.

JSON response and calling next() in Express

Is it possible, using Express 4, to send a JSON response to the front-end indicating that there was an error, as well as calling next(err) inside the Express middleware, so that the error can be handled by the server as well? Or are these calls completely mutually exclusive?
My current assumption is that you can do this:
app.get('/', function(req, res, next) {
res.json({ error : true });
});
and you can do this:
app.get('/', function(req, res, next) {
next(new Error('here goes the error message');
});
but that you can't do this
app.get('/', function(req, res, next) {
res.json({ error : true });
next(new Error('here goes the error message');
});
and you can't do this:
app.get('/', function(req, res, next) {
next(new Error('here goes the error message');
res.json({ error : true });
});
They aren't mutually exclusive. For example (instead of middleware I'm using route handlers to demonstrate, but the principle is the same for both):
app.get('/', function(req, res, next) {
res.json({ error : true });
next(new Error('something happened'));
});
app.get('/another', function(req, res, next) {
next(new Error('something happened'));
});
app.use(function(err, req, res, next) {
console.error(err);
if (! res.headersSent) {
res.send(500);
}
});
You could check res.headersSent in the error handler to make sure that a response is sent (if not, the error handler should send one itself).

Resources