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.
Related
I have an angular app being served from a node server as static files.
Everything works fine if I start on http://localhost:3000, all the angular routes work.
But if I put direct an address with an angular route in it (for example: http://localhost:3000/login) or if I refresh a page, I get the error: "TypeError: res.sendFile is not a function".
I already search here in stack overflow, but I couldn't find a solid answer to solve this.
This is the routes section of the app.js:
app.use("/api", commonRoutes);
app.use("/api/auth", authRoutes);
// This returns the static file, but only for http://localhost:3000
app.use((res, req, next) => {
res.sendFile(path.join(__dirname, "angular", "index.html"));
});
you have app.use((res, req, next) arguments in incorrect order. Try
app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "angular", "index.html"));
});
I am building a REST API based on express, I want to warn the user when he used the wrong HTTP verb for his request.
Currently, I am adding
app.all('/', (req, res) => {
answer(req, res, {code: 400, error: 'Wrong method'});
});
after each routes, and it is starting to be non negligeable, I d much rather have it at one place, and list all routes I want to listen to this.
Is there a way to do something like:
app.all(['/', '/signup', '/login'], (req, res) => {
answer(req, res, {code: 400, error: 'Wrong method'});
});
so that I only have one point of failure, instead of having to check every route?
Paths can be Regular expressions too, so something along the following should work:
app.all(/(signup|login)/, (req, res) => {
answer(req, res, {code: 400, error: 'Wrong method'});
});
Express uses path-to-regexp for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. Express Route Tester is a handy tool for testing basic Express routes, although it does not support pattern matching.
You can use /^(signup|login)\/(.+)/. See DOCS
In your case:
app.all(['/^(signup|login)\/(.+)/'], (req, res) => {
answer(req, res, {code: 400, error: 'Wrong method'});
});
You can define a function with your checks on url path and method and use it in a middleware you pass to the app to handle this error situation.
Just define it before your routes.
Here an example:
app.use(function(req, res, next){
if (checkIfIsWrongMethod(req)) {
answer(req, res, {code: 400, error: 'Wrong method'});
} else {
next();
}
});
Here is the expressjs FAQ.
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?
I'm getting a Node/Express API ready for production however have some questions/advice need help on:
1 - I'm using the npm package cors - did so for development to basically disable CORS, however now that I'm moving to production I only want certain URLS to be able to reach the API.
So to so this what I've seen is:
var corsOptions = {
origin: 'http://www.example.com',
methods: ['GET', 'POST']
};
app.get('*', cors(corsOptions), function(req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'});
});
However (from what I've seen) I'd need to do this for everyone request type e.g.
app.post('*', cors(corsOptions), function(req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'});
});
app.del('*', cors(corsOptions), function(req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'});
});
Is there an easier way to avoid such duplication?
2 - And the second question - I have a long list of API routes e.g.
router.post('/registerUser', function(req, res) {
...
}
Is it possible to place some kind of 'otherwise' line so that if a route doesn't match anything I've defined i can return something specific?
Thanks.
For first put cors as a middleware before your first route.
app.use(cors(corsOptions));
//routes down below
Explanation: Cors will be set for all the routes below for every request. As this middleware will be executed first.
For second put your otherwise or 404 route after your last route.
app.use((req,res,next)=>{
//Your message
res.send('Page Not Found');
});
Explanation: If any route will not be matched then this route will trigger.
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);