How to handle node.js errors properly - the standart way - node.js

For about developer errors that are made by mistake or undefined or something else that can crash the whole app:
Should I use this:
var domain = require('domain');
var d = domain.create();
d.on('error', function(err) {
console.error(err);
});
d.run(function() {
if (someom.sadjaslkd.asdasd=="yes") console.log("Yes");
// run more other things in the safe area
});
Purposely someom.sadjaslkd.asdasd is undefined.
OR should I use this:
try {
if (someom.sadjaslkd.asdasd=="yes") console.log("Yes");
// run more other things in the safe area
} catch(err) {
// handle the error safely
}
For about operation errors that are made not by mistake but due to client's faults:
Should I use this:
if (somethingWorng) res.status(400).json({status: "400", error: "Some custom error message to the user"});
OR maybe I should pass the error like this:
if (somethingWorng) throw "Some custom error message to the user";
OR maybe
if (somethingWorng) throw new Error("Some custom error message to the user");
Really there tons of ways to make this work. Is there a quick easy, readable, best practice?

Related

sequelize handling rejection in the create statement - catch not firing

The sequelize create statement has an error and I would like to handle that error. Since the create statement has the error I need to handle promise rejection. How do I do that in code? Tried to look at the sequelize documents but unable to work it out.
db.Employee.create(empData,
{
include:[
{
model: db.EmployeeDetails
}
]
}).then(function(newEmployee){
res.json(newEmployee);
}).catch(function(err){
return next(err);
});
The error is on the create and so the webpage just gives an internal server error. I was under the impression that the catch was something that handled the promise rejection and failure. In this case, how can I handle the promise rejection in code. An example would be greatly appreciated.
By doing next(err), by default, you send a 500 Internal Server Error message. If you use Express, and want to show a custom error, just append a status code which is not 5xx to the error:
General Usage:
const err = new Error("my custom error")
err.statusCode = 400
next(err)
In your snippet, do:
db.Employee.create(empData, {
include:[
{
model: db.EmployeeDetails
}
]
}).then(function(newEmployee){
res.json(newEmployee);
}).catch(function(err){
err.statusCode = 400
next(err);
});
If you haven't set your error handler in Express you will need to add somewhere at the end of the main file this:
// Error Handler
app.use(function(err, req, res, next) {
console.error(err)
if (!err.statusCode) err.statusCode = 500;
let msg = err.message
// Do not expose 500 error messages in production, to the client
if (process.env.NODE_ENV === "production" && err.statusCode === 500) {
msg = "Internal Server Error"
}
res.status(err.statusCode).send(msg)
})
Your webpage showing a 500 error means the issue was caught / working as intended. What you need to do is figure out how to handle displaying that error in a pretty format - this being a UI task. If you want a 'patch' for hiding the issue, change your return to a res. This will trick your browser with a 200 status and hide the error.
I do want to add, I recommend trying async/await for sequelize. There's a good amount of usage examples with it.
Promise
db.Employee.create(empData,
{
include:[
{
model: db.EmployeeDetails
}
]
}).then(function(newEmployee){
res.json(newEmployee);
}).catch(function(err){
// Temporary patch
res.json("pretty error message");
});
Async/Await version
async function createEmployee(empData) {
try {
return await db.Employee.create(empData, {
include:[ { model: db.EmployeeDetails } ]
});
} catch (err) {
// Handle error here
return err;
}
}

How do I handle errors for get API request

I have written an API to view logs of my server in browser. I tried but not getting how to do error handling. Please show how will you do error handling. I am new to node.js
app.get('/logs', function(request, response, next) {
res.sendFile('file', 'path');
});
Error handling looks something like this below.
app.get('/logs', async function(req, res) {
let something;
try {
something = await "file processing";
} catch (error) {
res.status(500).json({ error: error.toString() });
}
res.json({ something });
});
when you are fetching API from other endpoint, you can use promise or async-await
when something goes wrong in the try statement, then error will be catched
if you want to make error deliberately, using new Error() in try statement
you can also study express error middleware when trying to handle route errors.

Catching stripe errors using middleware and logging

I'm curious if there's a good way to handle this with express 4.0.
There are times where there is a problem with either Stripe, or my connection to Stripe that needs to be addressed. However, I obviously do not want users to know about this. I want to display a message 'There was a problem completing your order, please contact support.' while safely logging the message with some information for me to handle it.
I suspect I can do this in middleware. However, I'm not sure how. I would like to catch these errors as they are happening and dump them to a logfile of some kind (suggestions would be great) so I can handle it.
Is there a standard way of doing this? How would I accomplish this?
Thank you!
You're thinking about this the wrong way. Instead of exposing 3rd party errors, explicitly define each possible failure case in your route.
// bad
app.use(function (err, req, res, next) {
res.status(err.status).json({ error: err.message })
})
Instead mark errors to be exposed:
app.use(function (err, req, res, next) {
if (err.expose) {
res.status(err.status).json({ code: err.code, error: err.message })
} else {
reportError(err, req)
res.status(500).json({ code: "unknown", error: "unknown error" })
}
})
You need to re-throw actual api errors.
function createError(status, message) {
var err = new Error(message)
err.expose = true
err.status = status
return err
}
function changeCard(user, data) {
return postStripeCards(user, data)
.catch({ type: "card_error" }, function (err) {
throw createError(400, "invalid card")
})
}
Uncaught errors are programmer mistakes which should be reported and fixed. Anything that makes it through is a bug.
function reportError (err, req) {
// log error
console.error(err.stack)
// send to rollbar
rollbar.handleError(err, req)
// maybe send an email
mailgun.send({
from: "bot#myapp.com",
to: "me#gmail.com",
subject: "My App: " + err.message,
text: err.stack + "\n\n" + JSON.stringify(req),
})
// pager duty, airbrake, etc
}
It takes work, but it means your API is well-defined.

Using domain with serialport-node

I have the node-serialport library working fine in a happy-path situation, but I'd like to address error handling.
The particular test case I'm addressing at the moment is simply that the serial device isn't plugged in. Ideally, I'd be able to detect that a problem exists, and then just retry after a short delay.
The problem is that I keep getting the following error:
events.js:72
throw er; // Unhandled 'error' event
Error: cannot open /dev/ttyACM0
I would expect something like this, since the device isn't plugged in, but I need to catch it. try/catch obviously doesn't work, since it's asynchronous. So I am trying "domain", which appears to be the recommended way:
function reconnect() {
var d = domain.create();
d.on("error", function(err) {
console.error(err);
setTimeout(reconnect, RETRY_DELAY_MS);
});
d.run(function() {
var gps = new SerialPort("/dev/ttyACM0");
gps.on("open", function() {
console.log("Success!");
});
gps.on("error", function(err) {
console.error(err);
setTimeout(reconnect, RETRY_DELAY_MS);
});
});
}
I would expect this to have the desired effect, but I get the same error as above.
Does anyone see anything that I'm just not getting?
The trick is to provide a callback when instantiating the SerialPort object
var serial = new serialPort("/dev/ttyUSB0", { baudrate : 115200 },
function(error) {
if(error)
{
console.log("INIT ERROR: " + error.message + "\n");
}
});

How to capture the errors in node.js using uncaughtException

In my application i want to create own module to capture my application error using uncaughtException.If i create uncaughtException in same module means its capturing errors but if i create that uncaughtException in separate module.Then call that module means its not capturing erros.Can anyone help me to fix this issue.
module1.js
var errorModule=require('./module2');
var err = new Error('Something went terribly wrong');
errorModule.captureError(err);
module2.js
module.exports.captureError=function(err){
process.on('uncaughtException', function(err) {
console.log(err);
});
}
Try this:
// module1.js
var errorModule=require('./module2');
errorModule.captureErrors();
throw Error('Something went terribly wrong');
// module2.js
module.exports.captureErrors = function() {
process.on('uncaughtException', function(err) {
console.log('an error occurred', err);
});
};
A few things to notice:
process.on('uncaughtException', ...) installs an event handler to catch uncaught exceptions; your code tries to pass an error to it, but that seems to defeat what you're writing ('to capture my application error using uncaughtException');
Uncaught exceptions are errors which are thrown (throw Error(...));
If you want the code in your module1 to work, module2 needs to look like this:
module.exports.captureError = function(err) {
console.log(err);
};
But that has nothing to do with uncaughtException.

Resources