const express = require('express')
const app = express();
function middleWear1(req, res, next) {
throw Error()
}
function errorHandler(err, req, res, next) {
console.log("error handled");
res.end("error occured at server")
}
app.use(middleWear1)
app.use(errorHandler)
app.get('/', middleWear1)
app.listen(8000, () => {
console.log("server is listening");
})
when I do localhost:8000 I get "error handled" printed two times in NodeJS terminal.
can some one explain why is it happening?
Assuming you requested localhost:8000 through your web-browser, your browser will not only load http://localhost:8000/ but http://localhost:8000/favicon.ico as well. This is default browser behaviour.
Now, since you've setup middleWear1 to run for every request and the two requests are sent to your server, error handled gets printed twice to the console.
To answer you question from the comment:
In order to prevent middleWear1 running for all requests and only for your / route, you can do:
const express = require('express')
const app = express()
function middleWear1(req, res, next) {
throw Error()
}
function errorHandler(err, req, res, next) {
console.log("error handled");
res.end("error occured at server")
}
app.get('/', middleWear1)
app.use(errorHandler)
app.listen(8000, () => {
console.log("server is listening");
})
Related
I'm trying to handle errors produced in a Nodejs with Express app. I'm following Express error-handling guide but the errors didn't catched, and nothing appears on console and browser simply show Cannot GET /abc when request the incorrect url http://localhost:3000/abc
const express = require("express")
const app = express()
const port = 3000
const config = require("./config.js");
function logErrors (err, req, res, next) {
console.error(err.stack)
next(err)
}
function errorHandler (err, req, res, next) {
res.status(500)
res.render("error", { error: err })
}
app.all("/", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.get("/favicon.ico", (req, res) => res.status(204));
app.use(express.static("public"))
app.use("/zips/:idReq", express.static("zips"))
const generateZip = require("./generateZip")
const fmeForm = require("./fmeForm")
app.get("/", function (req, res) {
res.send("Hello World !")
})
app.use("/generateZip", generateZip)
app.use("/downloadForm", fmeForm)
app.use(logErrors)
app.use(errorHandler)
app.listen(port, () => console.log(`${config.nameServer} App listening on port ${port}`))
Any idea?
You need to include a common route handler to invoke error handling method at last
app.all('*', function (req, res, next) {
// Either invoke error handler method by raising new error
next(new Error('page not found'));
// Or simply return the response
res.status(404).send('page not found')
})
I am fairly new to express and want to know if there exists a global error catcher. I am working on an already existing code with all the controllers created and it would be rookie to implement try and catch in all the controllers. I need a global error catcher to that detects breaks in the code and responds to the client. is there an existing library for that or an existing code implementation.
If your controllers aren't asynchronous, you can simply add error handler after you registered all of your route
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
throw new Error('Something went wrong');
});
// Add more routes here
// Error handler
app.use(function (err, req, res, next) {
// All errors from non-async route above will be handled here
res.status(500).send(err.message)
});
app.listen(port);
If your controllers are asynchronous, you need to add a custom middleware to your controller to handle async error. The middleware example is taken from this answer
const express = require('express');
const app = express();
const port = 3000;
// Error handler middleware for async controller
const asyncHandler = fn => (req, res, next) => {
return Promise
.resolve(fn(req, res, next))
.catch(next);
};
app.get('/', asyncHandler(async (req, res) => {
throw new Error("Something went wrong!");
}));
// Add more routes here
// Error handler
app.use(function (err, req, res, next) {
// All errors from async & non-async route above will be handled here
res.status(500).send(err.message)
})
app.listen(port);
I am a beginner studying Nodejs.
I have recently studied node middleware and have created a simple game using middleware.
The purpose of the generated code is to respond to hello by connecting as root and then respond to the browser with 50% probability through the middleware.
However, I get the following error:
I did a search and found that res.send is not available after next ().
Is that correct?
But I could not figure out why and I did not realize why the code did not work.
code
const express = require('express');
var app = express();
app.use('/', (req, res, next) =>{
res.send('hello');
next();
});
app.use((req, res, next) => {
if (+new Date() % 2 === 0) {
console.log('continue');
res.send('lucky!');
next();
} else {
console.log('failed');
res.send('end');
}
});
app.use((req, res, next) => {
if (+new Date() % 2 === 0) {
console.log('continue');
res.send('lucky!');
next();
} else {
console.log('failed');
res.send('end');
}
});
app.listen(3000, () => console.log(`Example!`))
error
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
const express = require('express');
var app = express();
app.use(/^\/$/, (req, res, next) =>{
res.send('hello');
return;
});
app.use((req, res, next) => {
if (+new Date() % 2 === 0) {
console.log('continue');
res.send('lucky!');
next();
} else {
console.log('failed');
res.send('end');
}
});
app.listen(3000, () => console.log(`Example!`))
you cannot use res.send() twice
res.send() = Sends the HTTP response.
Consider the following Express app:
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('\n\nALWAYS')
next()
})
app.get('/a', (req, res) => {
console.log('/a: route terminated')
res.send('/a')
})
app.use((req, res) => {
console.log('route not handled')
res.send('404 - not found')
})
app.listen(3000, () => {
console.log('listening on 3000')
})
Visit /a console result:
ALWAYS
/a: route terminated
ALWAYS
route not handled
Can somebody explain why is that there is another middleware log? I was expecting only 2 lines of console log. Instead
ALWAYS
route not handled
has been logged.
This is a very common point of confusion. The likely cause is that you went to /a in the browser and the browser made two requests. One for /favicon.ico and one for /a (that's what browsers do when you go to a new site they haven't previously cached the favicon for - the little glyph they display that represents the web site in some places in the browser).
If you log the request URL in your middleware and in your 404 handler, you will see the details of what is happening:
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('\n\nRequest for: ', req.url);
next();
})
app.get('/a', (req, res) => {
console.log('/a: route terminated')
res.send('/a')
})
app.use((req, res) => {
console.log('route not handled for ', req.url);
res.send('404 - not found');
});
app.listen(3000, () => {
console.log('listening on 3000')
})
At the moment I have the following which sits below all my other routes:
app.get('*', function(req, res){
console.log('404ing');
res.render('404');
});
And according to the logs, it is being fired even when the route is being matched above. How can I get it to only fire when nothing is matched?
You just need to put it at the end of all route.
Take a look at the second example of Passing Route Control:
var express = require('express')
, app = express.createServer();
var users = [{ name: 'tj' }];
app.all('/user/:id/:op?', function(req, res, next){
req.user = users[req.params.id];
if (req.user) {
next();
} else {
next(new Error('cannot find user ' + req.params.id));
}
});
app.get('/user/:id', function(req, res){
res.send('viewing ' + req.user.name);
});
app.get('/user/:id/edit', function(req, res){
res.send('editing ' + req.user.name);
});
app.put('/user/:id', function(req, res){
res.send('updating ' + req.user.name);
});
app.get('*', function(req, res){
res.send('what???', 404);
});
app.listen(3000);
Alternatively you can do nothing because all route which does not match will produce a 404. Then you can use this code to display the right template:
app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.jade');
} else {
next(err);
}
});
It's documented in Error Handling.
I bet your browser is following up with a request for the favicon. That is why you are seeing the 404 in your logs after the 200 success for the requested page.
Setup a favicon route.
You can this at the end of all routes,
const express = require('express');
const app = express();
const port = 8080;
// All your routes and middleware here.....
app.use((req, res, next) => {
res.status(404).json({
message: 'Ohh you are lost, read the API documentation to find your way back home :)'
})
})
// Init the server here,
app.listen( port, () => {
console.log('Sever is up')
})
Hope it helpful, I used this code in bottom of routes
router.use((req, res, next) => {
next({
status: 404,
message: 'Not Found',
});
});
router.use((err, req, res, next) => {
if (err.status === 404) {
return res.status(400).render('404');
}
if (err.status === 500) {
return res.status(500).render('500');
}
next();
});
You can use this
const express = require('express');
const app=express();
app.set('view engine', 'pug');
app.get('/', (req,res,next)=>{
res.render('home');
});
app.use( (req,res,next)=>{
res.render('404');
})
app.listen(3000);
I wanted a catch all that would render my 404 page only on missing routes and found it here in the error handling docs https://expressjs.com/en/guide/error-handling.html
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(404).render('404.ejs')
})
This worked for me.
Very simple you can add this middleware.
app.use(function (req, res, next) {
//Capture All 404 errors
res.status(404).render("404.ejs")
})
404 error in a service is typically used to denote that the requested resource is not available. In this article we will see how to handle 404 error in express.
We need to handle the Error and Not-Found collectively as
Write two separate middleware for each,
// Import necessary modules
const express = require('express');
// Create a new Express app
const app = express();
// Define routes and middleware functions
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Catch 404 Not Found errors and forward to error handler
app.use((req, res, next) => {
const error = new Error('Not Found');
error.status = 404;
next(error);
});
// Error handler middleware function
app.use((err, req, res, next) => {
// Set status code and error message based on error object
res.status(err.status || 500);
res.send({
error: {
message: err.message
}
});
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});