How do you catch all errors in SailsJS - node.js

I'm new to Node and Sails and have been struggling with this problem for a couple of weeks now. I need to log (eventually to a file or database) all errors that occur in our Sails app. I have found a couple of answers that come close to solving this, but none seem to work 100%. I have setup things based off of the answer from this question
When using Sails v0.9.16 I setup my logging in the config/500.js file, but when using test code...
t.t;
... in my controller, Sails just prints out "ReferenceError: t is not defined". It never goes to 500.js. In Sails v0.10.0-rc5 the same test code will get to my custom 500 middleware (shown below).
Problem is in Sails v0.10.0-rc5 it appears that the middleware Router handles 400 error message before getting to my custom 400 middleware.
We have not committed to which version we are going to use, but getting this to work in one or the other would probably make up our minds.
So how do I get all errors that happen? If I am on the right track, what am I missing to get this to work?
Thanks in advance!
Not much code to show for v0.9.16...I don't think I changed anything other than adding a sails.log in the 500.js file...
Below is the custom middleware setup for v0.10.0-rc5 ...
loadMiddleware: function(app, defaultMiddleware, sails) {
// Use the middleware in the correct order
app.use(defaultMiddleware.startRequestTimer);
app.use(defaultMiddleware.cookieParser);
app.use(defaultMiddleware.session);
app.use(defaultMiddleware.bodyParser);
app.use(defaultMiddleware.handleBodyParserError);
app.use(defaultMiddleware.methodOverride);
app.use(defaultMiddleware.poweredBy);
app.use(defaultMiddleware.router); //400s do not make it past this...
app.use(defaultMiddleware.www);
app.use(defaultMiddleware.favicon);
app.use(function(req, res, next ) {
sails.log("400 error caught in middleware - " + err.stack);
next();
});
app.use(function(err, req, res, next){
sails.log("500 error caught in middleware - " + err.stack);
next(err);
});
}

In Sails v0.10, you have custom responses to handle errors, so you don't need to provide custom middleware as in your example. By default, most errors (i.e. those not specifically triggered by res.forbidden(), res.notFound() or another handler) will be served by the serverError response that lives in api/responses/serverError.js. You can customize this to do whatever you like.
If you've upgraded a v0.9 app to v0.10, you might not have the api/responses folder. No problem; just use sails new whatever in an empty directory to generate a new v0.10 project and copy the api/responses folder from the new project to your old one!

Related

How to create an error handling "interceptor" for NodeJS

So I did a lot of digging around the internet, and I have been unable to come up with the answer to my problem. My goal is that I want to print any errors that are logged to the console into a database. However, I have gone far enough into my project that it would be a pain to go back into my try...catch... blocks and edit them with an error extender, or to just create my own function in the catch area.
I wanted to know: is there a specific way to create an error interception in NodeJS? I mean, I assume that whenever an error is logged to the console, the code fires some sort of event, and I guess I am looking for something like:
process.on(error, async (e) => { // my code here })
Is that at all possible? Is there a module that will allow me to do this? For context, I am running the latest version of Node/NPM on a headless Ubuntu 18.04 server, and am using pm2 to control my program processes.
You can use middleware at the end of the main file of your app
var bodyParser = require('body-parser');
app.use(bodyParser());
...
...
app.use(function(err, req, res, next) {
// Error handler logic
});
You can find more about this in the express documentation https://expressjs.com/en/guide/error-handling.html

Centralized Error Handling & Reporting for node.js

I want to have a system which will either send me a text message or email based on severity of error on respective occurrence. I have done some research on the subject but I haven't been able to simplify matters.
All in all my end goal is to get notification whenever something is going wrong with my production server. In case of serious issues which are not caught at all I have used process's uncaughtException and for specific routes which are called via separate API calls I can simply use try catch blocks.
My first issue is I cannot handle errors thrown from different routes directly via my main server file.
Second is I'll have to write same kinda' code in every route for exception handling. If something could just listen to all the errors from main server file then I can do things easily.
You can use an error handling middleware in Express:
app.use(function (err, req, res, next) {
console.error(err.stack);
// do whatever you need to send a notification
res.status(500).send('Internal error');
});
See the documentation on the error handling in Express:
https://expressjs.com/en/guide/error-handling.html
Everything you ask about is explained very well there.

Sailsjs fiber integration

Im trying to integrate SailsJS with synchronize, which is based on fibers.
http://alexeypetrushin.github.io/synchronize/docs/index.html
As commented on other fiber libraries, I added a custom middleware to create a new fiber per the request.
var sync = require('synchronize');
...
...
sincronized: function (req, res, next) {
sync.fiber(next);
}
The middleware is executing I can confirm via a console.
But then when I try to do anything fiber related, such as sync.defer() in one of my controllers, I do get an exception.
error: Error getting xxxxxx Error: no current Fiber, defer can't be used without Fiber!
As sailsjs is based in express, adding this middleware should be enough, although I have no idea what I might be missing.
As a side comment, if I create a fiber inside the controller method itself, everything works as expected.
Thanks.

Passing errors to client in express

How do you pass nice error messages to clients in express?
app.use(errorHandler);
function errorHandler(err, req, res, next) {
res.send(err);
}
app.post('/login', usernameIsValid, pwdIsValid, createToken);
In usernameIsValid I create a new Error with a message and status and call next(err). Now this bypasses pwdIsValid and createToken like it should BUT the weird thing is my errorHandler logs the error without a console.log. Am I using the default error handler in express somewhere? How do I turn it off? I have tried both production and development for NODE_ENV.
On the client xhr.responseText is my error.message + what looks like a stack trace? I've even tried just to send err.message but it looks the same.
One way to handle this mess is to make each middleware (if there is an error) create an error string like req.data.err = "invalid username" and then make sure each following middleware checks req.data.err if the string is present. But this is tedious as hell >_<
I solved it. You need to apply the error handler app.use(errorHandler) dead last after all other routes. This disables the built-in error handler. Now you may pass pretty error messages to the client.
Read more here.
edit: process.env.NODE_ENV does not matter.
From the express documentation site
If you pass an error to next() and you do not handle it in an error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace. The stack trace is not included in the production environment.
So if you want to avoid the stacktrace you only need to execute your application with the NODE_ENV set to production.
Run you application as follows:
$ NODE_ENV=production node file.js

Nodejs Express sendStatus error

The web app uses express for the server, nodejs as the language, mongodb as the database and mongoose as the wrapper. Express is running a server at port 3000 and I'm trying to implement a basic CRUD for a collection.
I've used restify before and normally doing a res.send(406, "err - body"); doesn't cause any issues however I can't seem to figure it out with express.
Looking at express' documentation, res.status(404).send('Bad Request'); is how you send a status code with a custom message back. It works when there's some sort of invalid input but when I try to save to mongodb
newSchema.save(function(err){
if (err) {
res.status(500).send('error saving');
} else {
res.sendStatus(200);
}
});
and call res.sendStats(200); it gives me the error: Error: Can't set headers after they are sent. When using a httprequester, the error is 404 and Cannot POST /user/create.
Are you sending another response afterwards? Ie... maybe you're doing something like:
if (!err){
res.send()
}
wherever the function is called (or after the code you pasted). And obviously, this could be the source of your error, since you'd be sending two separate responses.
Apparently, it's not a good idea to copy restify code into express. I had a next(); which doesn't work with express or it does but as of right now, I don't need to use it.
Instead of res.sendStatus(), I changed to res.send(), and it works beautifully.

Resources