I am currently trying to create a server using NodeJS to provide RESTful APIs for inserting records into a SQLite database. While I am able to retrieve records, I am having issues handling SQLite related errors (e.g. unique constraints):
function insertUser(name, password, response) {
db.run(insert_stmt, [name, password, new function(err) {
if (err != null) {
handleError(err, response);
}
else if (response != null) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("User registered.");
response.end();
}
}, function(err) {
handleError(err, response);
});
}
function handleError(err, response) {
console.log(err.message);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Registration error.");
response.end();
}
The problem is that the code appears to be hitting both the second and the third function, as the response object appears to be closed whenever I try to create a response in the handleError method. In my browser, I am getting the "User registered." message as a response.
SQLITE_CONSTRAINT: UNIQUE constraint failed: Users.name, Users.phone_no
events.js:85
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:413:15)
at handleError (/Users/kli/Documents/Node.js/db.js:59:14)
at Statement.<anonymous> (/Users/kli/Documents/Node.js/db.js:39:3)
at Statement.replacement (/Users/kli/node_modules/sqlite3/lib/trace.js:20:31)
at Statement.replacement (/Users/kli/node_modules/sqlite3/lib/trace.js:20:31)
What is the correct way of handling errors in NodeJS? I tried using the process.on('uncaughtException', function(err) method, but I need the response object in order send a response to the client, indicating the error that has occurred.
Related
So, in this piece of code I'm trying to use findOne to find and delete a particular dishId from my Favorites document. The code is working fine if I send a valid dishId but when I enter a wrong dishId the code does throw err; and the Node server stops with this error.
events.js:292
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'dishes' of null
And then I've to do npm start again. So how should I tackle this? I don't want server to stop. I want it to keep going so that I can do further requests. Here's my code.
favoriteRouter.route('/:dishId')
.delete(cors.corsWithOptions, authenticate.verifyUser, (req,res,next) => {
Favorites.findOne({user: req.user._id, dishes: req.params.dishId} ,(err, favdel) => {
if(err) {
throw err;
}
else {
favdel.dishes.pull({_id:req.params.dishId});
favdel.save();
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(favdel);
}
})
});
The error is pretty clear: you're blindly accessing a property without first checking whether it exists, so: check if favdel.dishes exists before you try to get data out of it. And if it doesn't, make error handling kick in, in a way that makes sure to send the correct HTTP error code.
...
if (!favdel || !favdel.dishes) {
// only you know which 4xx or even 5xx error this should be
return next(new Error("..."));
}
favdel.dishes.pull({_id:req.params.dishId});
favdel.save();
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(favdel);
...
I have a script that posts to an endpoint, like so using the node.js request module https://github.com/request/request
const options = {
url: path,
formData: {
name: name,
bundle: fs.createReadStream(path)
}
}
request.post(options, function(err, httpResponse, body) {
if (err) {
console.log('Error!')
} else {
console.log('Success!')
}
})
And I'm trying to catch when the post fails and doesn't work. I tried purposely uploading something and got a 400 response back, but it still came back with success. Is there a more appropriate way to handle error catching with the request module?
The request library doesn't populate the error argument of the request callback unless there is an actual error in the transmission or some other runtime issue. See this issue on the GitHub: 404 error does not cause callback to fail #2196.
Currently request does not handle the HTTP errors. You can wrap the
callback and add your own logic there.
To check for HTTP errors, check the statusCode property of the response argument:
request.post(options, function (err, httpResponse, body) {
if (err || httpResponse.statusCode >= 400) {
return console.error("Something went wrong");
}
console.log('Success!')
});
I am developing an SOAP Server in NodeJS (v6.9.4) using the SOAP library. I have to request some data from a Postgres database. I choose to use the pg-promise lib.
SAOP Services are implemented like this :
TestConnection: function (args, cb, headers, req) {
db.any("select * from users where active=$1", [true])
.then(function (data) {
return {};
})
.catch(function (error) {
throw {
Fault: {
faultcode: faultCode,
faultstring: faultString,
detail: {
"ns:FaultInformation": {
"ns:FaultCode": detailedFaultCode,
"ns:FaultText": detailedFaultText
}
},
statusCode: 500
}
};
});
}
In case of error during the database connection/request, I need to return a SOAP Fault. On the SOAP lib, you can do this by throwing a new Fault object.
In this example, I want to throw it in the catch block. I know it's not the right way to do this and I am facing this issue :
UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 3): [object Object]
How can I throw my SOAP Fault exception in the main service function. I tried without success the setTimeout solution. Is the promise a good solution for PG queries ?
I found a solution myself by using the soap callback function (cb) provided by the soap lib. The following code should return a Soap Fault exception under an Async service implementation :
TestConnection: function (args, cb, headers, req) {
db.any("select * from users where active=$1", [true])
.then(function (data) {
cb({});
})
.catch(function (error) {
cb({
Fault: {
faultcode: faultCode,
faultstring: faultString,
detail: {
"ns:FaultInformation": {
"ns:FaultCode": detailedFaultCode,
"ns:FaultText": detailedFaultText
}
},
statusCode: 500
}
});
});
}
I have a http-function that responses on a request as usual:
app.post('/file', function(res, req){
write(req.body.file, function(err, id){
if(!err)
res.send({id:id});
else
{
res.status(500);
res.send({ error: 500 });
}
});
});
I post a file that is beeing written to the filesystem. When the file was written, I send a response back to the client. Now the client lost the connection to the internet, the server can't send the response, throws an error and gets killed.
Error:
Error: Request aborted
at IncomingMessage.onReqAborted ....
....
http.js:689
throw new Error('Can\'t set headers after they are sent.');
How can I catch this exception?
To catch those errors you can res.on('error', function(err) {}) or req.socket.on('error', function(err) {}) to catch lower-level errors, although I think the lower-level errors do bubble up to the request/response object also.
I should also point out that your route parameters are flipped, it should be (req, res), not (res, req).
I have a branch in a function that isn't currently being tested. It's an error handler coming from a request operation (using the node module of the same name). Here is the particular line:
request(url, function (error, response, body) {
if (error) return cb(error);
Here is the test:
describe("handles errors", function() {
it("from the request", function (done) {
var api = nock('http://football-api.com')
.get('/api/?Action=today&APIKey=' + secrets.APIKey + '&comp_id=1204')
.reply(500);
fixture.getFixture(FixtureMock, function (err, fixture) {
expect(err).to.exist
done();
});
});
Spec fails:
Uncaught AssertionError: expected null to exist
So either sending a 500 status code as a response with no body does not cause an error in the request callback, or I'm testing the wrong thing.
Use replyWithError from doc:
nock('http://www.google.com')
.get('/cat-poems')
.replyWithError('something awful happened');
This variant of #PiotrFryga's answer worked for me, as my request callback(err, resp, body) was actually checking for the "ETIMEDOUT" error code in err:
nock('http://www.google.com')
.get('/cat-poems')
.replyWithError({code: "ETIMEDOUT"});
The only found workaround is to simulate timeout
nock('http://service.com').get('/down').delayConnection(500).reply(200)
unirest.get('http://service.com/down').timeout(100).end(function(err) {
// err = ETIMEDOUT
});
source