Express next() header error - javascript

In a route I have this:
if (elements.length <= 0) {
var msg = 'no elements found';
console.error(msg);
var err = new Error('Not found');
err.status = 404;
err.message = msg;
next(err);
}
console.log('Found ' + elements.length + ' elements');
res.setHeader('Content-Type', 'application/json'); /*error*/
res.status(200).json(elements);
res.end();
The error handler that is defined last in app.js:
// development error handler
app.use(function(err, req, res, next) {
res.type('application/json');
res.status(err.status || 500);
res.json({
message: err.message,
error: err
});
});
I see that the error is sent as response in json.
But I get this error on the line marked with /error/:
Can't set headers after they are sent.
Why is express returning from the error handler?
I can see that it is continuing the execution of the route (from the console.log)
Why is it continuing execution of the route?

Inside if statement correct:
return next(err);

Related

nodejs api request function error handling crashes app

I'm trying to make an api call and pass it into a function that stores it into mongodb. The problem is that the entire site crashes when I try to handle errors instead of redirecting to the error page. All my other functions work, it's just the request function containing the api call that doesn't.
Instead of redirecting, I only get the error messages in the terminal.
Here's my code for it:
index.js
router.post('/',async function(req,res){
var {title,date,loc,count, save,del,update,csv} = req.body;
var {username} = req.session;
console.log(req.body);
var url = `http://api.openweathermap.org/data/2.5/weather?q=${loc}&appid=${API_KEY}&units=metric`
if(save){
//weather api
request({ url: url, json: true }, async function (error, response) {
if(error){
throw new Error ('type error');
}
else{
console.log('Current weather: '
+ response.body.main.temp
+ ' degrees celsius'
);
let w = JSON.stringify(response.body.main.temp);
console.log(w)
await db.addItem(username,title, loc, count, w, date);
}
});
res.redirect('/');
}
app.js
app.use('/', indexRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Here is what my terminal looks like when the app crashes:
terminal error message
You have not describe what to do if an error occurs in the else statement of the request call. So if an error occurs it will crash.
Since you are using async...await in the callback to insert into the db, you can get the functionality you want by wrapping it in a try...catch block and moving the redirect into the catch:
request({ url: url, json: true }, async function (error, response) {
if(error){
throw new Error ('type error');
} else {
try {
console.log('Current weather: '
+ response.body.main.temp
+ ' degrees celsius'
);
let w = JSON.stringify(response.body.main.temp);
console.log(w)
await db.addItem(username,title, loc, count, w, date);
} catch (error) {
console.log(error);
res.redirect('/');
}
}
});
However, the throw new Error('type error') will still cause the app to crash here. If you want to also redirect in this case, then you can add a res.redirect('/') there as well instead of throwing, or wrap the entire request call in a try...catch so that the catch block will also catch that thrown type error:
try {
request({ url: url, json: true }, async function (error, response) {
if(error){
throw new Error ('type error');
}
else{
console.log('Current weather: '
+ response.body.main.temp
+ ' degrees celsius'
);
let w = JSON.stringify(response.body.main.temp);
console.log(w)
await db.addItem(username,title, loc, count, w, date);
}
});
} catch (error) {
res.redirect('/')
}

JS runtime errors in Express

I have a basic Express app which has a few routes.
One is as such:
router.post('/upload', (req, res) => {
let audioFile = req.files.audioFile;
const file = __dirname + '/../' + req.body.uploadLocation + audioFile.name;
mp3.mv(file, function(err) { // <--- HERE
if (err) {
return res.status(500).send(err);
}
res.send('File uploaded!');
});
});
Now, if you would try to upload a file to this route you would get a 500 and that's it. The highlighted line is a result of me changing variable name. Is there any way to get it so that it prints out the actual error? I am tripped up by this so often and it would make it an awful lot quicker if the terminal output just told me the normal JS error like it does on the browser or when I'm running node normally.
In Express there is middleware to handle errors. In the a base setup of express you'll find:
// error handler
app.use(function(err, req, res, next) {
...
// render the error page
res.status(err.status || 500);
res.json({ error: err });
});
Just add a console.error there:
// error handler
app.use(function(err, req, res, next) {
console.error(err.stack); // <- HERE
...
// render the error page
res.status(err.status || 500);
res.json({ error: err });
});

Creating node server and setting error handlers in node js

I want to create a function that return a http.Server and
Serve the text of the file testText.txt in the body of the HTTP response
when a GET request is made to the '/' route.
Parse the request for a "paragraphs" parameter.
That parameter must be an integer and represent the number of
paragraph you want to receive starting from the beginning of the test text.
Return the appropriate content in the body of the response.
If any error happens, return a 500 error.
If the provided route is not known, return a 404 error.
here is what i have so far
function makeServer() {
return http.createServer(function(req, res){
if(req.url === '/'){
fs.readFile('testText.txt', function(err , para){
console.log("Data", para);
res.end();
});
console.log("The end");
}
}
I would expect to do something like this,
var express = require('express');
var app = express();
//Handle 404 here
app.use(function (req, res, next) {
res.status(404).send({
message: "Page Not Found"
})
});
Inject the GET request to your default route
app.get('/', (req, res) => {
// **modify your existing code here**
fs.readFile('testText.txt', (e, para) => {
if (e) {
res.status(500).send({
message: "Something went wrong"
})
}
res.send(para);
});
});
app.listen(5555);
As you have mentioned in your question use that err object inside the function such as below:
function makeServer() {
return http.createServer(function(req, res){
if(req.url === '/'){
fs.readFile('testText.txt', function(err , para){
if (err) {
res.status(500).send({
message: "Something went wrong"
})
// error handling
} else {
console.log("Data", para);
res.end();
}
});
console.log("The end");
}
}
Firstly, Welcome to the node world...
1) Work with file in res
Please refer this answer. It will help you.
2) Error code 500 if any error
res.status(500).json({success: 0, error 'Something went wrong'});
3) For handle 404 if route not matched
var createError = require('http-errors');
//Install via this command-> npm i http-errors --save
app.use(function (req, res, next) {
next(createError(404));
});

err is blank but err.message exists on expressJS

In ExpressJS app final app.use which is using for error handling
app.use(function(err, req, res, next) {
res.status(err.status || 500);
console.log('as',typeof err);
// res.render('error1', {
// message: err.message,
// error: {}
// });
res.json(err.message)
});
When I log err it print as {} ,but when I log err.message it show string like 'obj is not defined'. Why this happens and how I can see all the keys of err object like message .
app.use(function(err, req, res, next) {
if(err){
res.json(err)
}
else{
//err is {}
}
});
If it is not error, then the err will be null.

Node.js express next error handler

My code looks like this
app.get('/', function(req, res, next) {
if (id==8) {
res.send('0e');
} else {
next();
}
});
app.use(function(err, req, res, next){
res.send(500, '<h1>Oops! what happened?</h1>');
});
So. the next() function is called the message Ooops! what happened should appear on screen but instead a message ' Cannot GET / ' appears
You can use node.js built in uncaught exception, just put this code inside your server.js
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
//you can also email this error
});
or follow this link
http://masashi-k.blogspot.com/2012/12/express3-global-error-handling-domain.html
Error handlers are only called if next() was called with an Error object.
So to trigger your error handler you'd have to do:
app.get('/', function(req, res, next) {
if (id==8) {
res.send('0e');
} else {
next(new Error('Fake error occurred'));
}
});
app.use(function(err, req, res, next){
res.send(500, '<h1>Oops! what happened?</h1>');
});

Categories