I use Express middleware to check request type, but I'm getting surprising results, here is my middleware code:
app.use(function (req, res, next) {
console.log(req.method);
next();
});
And here is console output I get:
POST
GET /parse/login 404 528.160 ms - 57
What can cause such behaviour and what can be the way to avoid it?
Related
I'm using NodeJS with Express and when an Endpoint is not found Express returns
I'd like to return a Custom 404 Message instead of the above image whenever an Endpoint is miss-typed.
I've tried adding the following to app.js
app.use(function (req, res, next) {
res.status(404).send("Sorry can't find that!")
})
But this just returns ALL endpoints with
Sorry can't find that!
You need to make that this the last 'route' in app.js
app.use(function (req, res, next) {
res.status(404).send("Sorry can't find that!")
})
The order your specify your routes is important.
While coding my app, I sometimes had a little mishap when typing my URLs in the browser, and thus sometimes got the error message:
Cannot GET /some/route
Which was true, since the route may was not defined.
But since this app is planned to enter production, I kinda don't want to use this flat message as my "error page".
Looking into the Express 4 docs, they tell me to .use() a middleware with 4 arguments. I did that. But I'd still get this issue...
Turns out that this message comes from the finalhandler module and my bet is, that this middleware comes before my error-catching, 4-argument middleware.
Here is a basic express app that I threw together while trying to find a solution:
var app = require("express")();
app.use("/yo", function(req, res, next){
res.send("Yo!");
});
app.use(function(error, req, res, next){
res.send("An error: "+error);
console.log(error);
});
app.listen(10000);
Accessing /yo works. But, / or /derp yields the Cannot GET message instead of my little middleware.
So, how is this done correctly, now?
The error middleware is only for actual errors, such as a middleware or route handler throwing an exception or passing an error to next().
If you want to provide a route handler for requests that do not match any existing routes, then just add a middleware after all of your app's routes/middleware like:
var app = require("express")();
app.use("/yo", function(req, res, next){
res.send("Yo!");
});
app.use(function(req, res, next) {
res.send('Could not route your request!');
});
app.use(function(error, req, res, next){
res.send("An error: "+error);
console.log(error);
});
app.listen(10000);
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.
Hi I'm developing my first Node.js application and I found my first issue in something really basic, I can't catch the HTTP errors (404, 500, ...)
I've followed the doc (I think so) but I suppose that I'm missing something.
This is my code:
var express = require('express')
app = express()
app.use(express.logger('dev'));
app.get('/', function(req, res) {
res.send('Hellow World!!!')
})
app.use(app.router);
app.use(function(err, req, res, next) {
console.error('Oh!! ERROR');
console.error('My ERROR: ' + JSON.stringify(err));
});
app.listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
Thanks in advance.
So the way express works is if it hits the end of the entire stack of middleware and route handlers and nothing has responded yet, it's going to send the fallback 404 response automatically without raising an error. This is why your error handling middleware isn't being called. By default, express doesn't consider a 404 an error, which is probably the right way to think of it.
If you want to customize this, you can put a middleware at the end of your stack to either serve a custom 404 page directly or call next with an error if you prefer that way.
app.get('/'...
app.get('/two'...
app.get(/'three'...
app.use(middleware1...
app.use(middleware2...
app.use(app.router);
app.use(function (req, res, next) {
//Option 1: respond here
return res.status(404).render('my_404_view');
//Option 2: trigger error handler
return next(new Error('404ed!'));
}
Option 2 will trigger your error handling middleware. There you will have to get info from the error object to determine the desired view to render and status code to send. I personally define an errors.NotFound class that has a 404 code and lets me render a friendly 404 page view.
I am trying to setup error handling for my express app and running into the following problem.
I defined an error middleware and add it as the last middleware:
// error handler
app.use(function(err, req, res, next) {
console.log('JUST TESTING. ERROR HANLDER HAS BEEN CALLED...');
next(err);
});
Now I would expect this middleware to be called whenever an error occurs:
app.get('/datenschutz', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
});
However my middleware is never called! The browser does display the stack trace however.
This seems that there is another middleware that is catching this error and processing it before I can do anything about it.
The problem is that I have no clue where this middleware could be defined, as I have a very simple setup:
// setup ssl for local testing
var
app = express();
app.
use(express.static(__dirname + '/public')).
use(express.bodyParser()).
use(express.cookieParser());
Why is my error handling middleware not being called?
Where is this 'default' error handling taking place?
Thanks!
* EDIT *
I see that the middleware is indeed working. However this is the case if I call it from another middleware function.
However it is not being invoked if the error occurs inside a function defined as an express route (GET, POST, etc..). This is very strange.
If I add my error middleware to the route callbacks it then works:
app.get('/testError', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
}, function(err,req,res,next) {
console.log('This error handler is called!!');
return next();
});
* EDIT 2 - FOUND ACCEPTABLE WORKAROUND **
I am surprised it has to be done this way. As I had read many entries/questions about error handling in express and never found this possibility mentioned.
However it seems that if an error ocurrs inside a route callback regular error middleware handlers will not pick it up. You will need to define an error handler at route level.
app.all('*', function(err,req,res,next) {
console.log('This is a global error handler at route level....');
return next(err);
});
I had this problem as well, but I couldn't figure out why it wasn't working even though I set my error handler after the app.user(app.router). As it turns out, I already had an error handler that I wasn't aware of.
Specifically, if you use the express cli to generate an app like I did, it will automatically add in this in:
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
Unfortunately for me, I added a bit more middleware to my app, which consequently obscured this statement and thus prevented my custom error handler from being called.
Simply remove that and then it should work properly.
On a side note, I should mention that the original solution still worked - even with the app.use(express.errorHandler()).
app.all('*', function(err,req,res,next) {
console.log('This is a global error handler at route level....');
return next(err);
});
Updated answer for Express 4 users from the Express 4 docs. See example from docs below. Note that app.router is deprecated and no longer used. I also added a dummy route to make the ordering clear:
"You define error-handling middleware last, after other app.use() and routes calls; For example:
var bodyParser = require('body-parser');
app.use(bodyParser());
app.get('/', function(req, res) {
res.send('hello world');
})
app.use(function(err, req, res, next) {
// logic
});
"
EDIT 2 (sabtioagoIT) works. But just for those who missed it, emostar's solution also works.
I understood to move the error handling 'use' call to the end, but there seems to be an easier option as emoster suggests, use app.router (before the error handling 'use' call).
instead of making
app.get('/datenschutz', function(req, res, next){
return next(new Error('Just testing')); // handle everything here
});
you can install express-async-errors
and just make
app.get('/datenschutz', function(req, res){
throw new Error('Just testing');
});
it works as expected