How to capture the error to redis in node.js - node.js

In my application im using redis database with node.js.Now i want to build error capture module .How can i capture error in redis.Using Airbrake(https://github.com/felixge/node-airbrake) we can capture error but how can i do that on my own using redis in node.js.

If you look at the code for node-airbrake, you'll notice this:
Airbrake.prototype.handleExceptions = function() {
var self = this;
process.on('uncaughtException', function(err) {
self._onError(err, true)
});
};
So, you could implement your own uncaughtException handler (although some say that doing so is bad form, but that's another discussion) and store your errors in Redis.

Related

AngularJS Mongoose error handling

I've build a simple application with AngularJS. Part of this application is calling REST services. For that, I'm using mongoose. Everything works great, but I'd like to better handle errors. A sample code could be :
Express:
DBCollection.find({}, function (err, tuples) {
if (err) {
console.log('Error!');
}
res.send(JSON.stringify(tuples));
});
AngularJS:
DBService.query(function (res) {
$scope.data.lists = res;
});
The problem I'm faced with is as follow. Imagine I've got an error on the mongodb server side. I've got an error, so I log it in the console and then ? What happens on the angularjs/front-end side ? If I send the error as a http response, I suppose angular would interpreate it as the response of the query but with unexpected content and produce an exception ? how to deal with that ?
Angular is like Santa, it knows when responses are bad or good. There are 2 solutions, ones solutions is to create an error handler on each request. The other is to use $httpProvider.interceptors to globally handle errors before they become a problem on an individual request level.
Option 1
DBService.query(function (res) {
scope.data.lists = res;
},function(errorResult){
console.log(errorResult); // <- take a peek in here, find something useful
});
Option 2
$httpProvider.interceptors.push(['$q',function($q) {
return {
'responseError': function(rejection) {
console.log(rejection); // <- take a peek in here, find something useful
return $q.reject(rejection);
}
}
}]);

Meteor client synchronous server database calls

I am building an application in Meteor that relies on real time updates from the database. The way Meteor has laid out the examples is to have the database call under the Template call. I've found that when dealing with medium sized datasets this becomes impractical. I am trying to move the request to the server, and have the results passed back to the client.
I have looked at similar questions on SA but have found no immediate answers.
Here is my server side function:
Meteor.methods({
"getTest" : function() {
var res = Data.find({}, { sort : { time : -1 }, limit : 10 });
var r = res.fetch();
return (r);
}
});
And client side:
Template.matches._matches = function() {
var res= {};
Meteor.call("getTest", function (error, result) {
res = result;
});
return res;
}
I have tried variations of the above code - returning in the callback function as one example. As far as I can tell, having a callback makes the function asynchronous, so it cannot be called onload (synchronously) and has to be invoked from the client.
I would like to pass all database queries server side to lighten the front end load. Is this possible in Meteor?
Thanks
The way to do this is to use subscriptions instead of remote method calls. See the counts-by-room example in the docs. So, for every database call you have a collection that exists client-side only. The server then decides the records in the collection using set and unset.

Unable to handle exception with node.js domains using express

I want to use Node.js Domains to catch exceptions. It is working so far, but there is one place I can't get domains to catch the exception. exception2 in the callback is caught and handled in the domain.on('error') handler, but exception1 is not caught. The odd thing is that when exception1 is thrown, it doesn't shutdown Node like I would expect. Here is my example app:
var domain = require('domain');
var request = require('request');
var express = require('express');
var serverDomain = domain.create();
serverDomain.on('error', function(err) {
console.log("Server Domain Error: " + err);
});
var app;
serverDomain.run(function() {
app = express();
app.listen(3000);
});
app.use(function(req, res, next) {
var reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
reqDomain.on('error', function(err) {
console.log("Req Domain Error: " + err);
reqDomain.dispose();
next(err);
});
next();
});
app.get('/', function(req, res) {
var uri = "http://google.com";
exception1.go();
request.get({url:uri, json: {}},
function (error, response, body) {
if(response.statusCode === 200) {
exception2.go();
res.send('Success getting google response');
}
});
});
To get exception2 to execute, I comment out exception 1.
The problem is that the exception happens during Connect's routing, which has both a try/catch block around its execution, as well as a default error handler which prints out stack trace details when running in a non-production mode. Since the exception is handled inside of Express, it never reaches your outer layer for the domains to handle.
How it differs from exception2 is that the handler function for the '/' route is executed directly by that Connect block, in the same stack as the original call that went through Express. The second exception occurs in a callback, after some I/O operation has returned, and therefore is executed by a stack originating from Node's event loop I/O handler, and so the try/catch of Express isn't available to snag that exception and save the app server. In fact, if you comment out all the domain stuff, and trip exception2 it crashes Node.
Since only unhandled exceptions are routed to the domain mechanism, and since exception1 has a try/catch visible in it's call stack above it, the exception is handled, and not forwarded to the domain.
Connect-domain allows you to catch all errors for connect modules including express.
Connect-domain
https://github.com/baryshev/connect-domain
The example for express3:
http://masashi-k.blogspot.com/2012/12/express3-global-error-handling-domain.html
#user1007983
No, in production, the try/catch handling still exists in Connect/Express. The way to solve it is to add your own try/catch block in the "root" which you can then use to emit an "error" event to the domain before connect sends the error response.
try {
// .. code here ..
} catch (err) {
domain.emit('error', err);
}
Another way to get around it is to just disconnect from the handler, like wrapping your code in a setImmediate block
I've tried try/catch blocks (which may not work the way you think with async code). I've tried node domains in several different ways. But I was unable to handle an exception thrown in a 3rd party lib (sequelize). Why did I get the exception? Well, it was because the SQL that was generated was not well formed. (My fault).
Anywho, the solution that worked best for me and my (small) project was to use forever. Let the exceptions happen, but fire up node again if they do. I doubt it is the most elegant solution, but it works for me and my small project.
With a larger project, domains combined with the clustering API might be a good choice.
Winston is another choice. It might be cool to combine forever with winston so that if you DO get an exception, you can have winston email you, so you can fix the code. Meanwhile, forever will happily restart the app for you.
I came across this problem while testing my domain-based error handling.
I went with the approach suggested here by Issac, with a couple of minor changes: use 'domain.active' to get the currently active domain and emit the error event on that, and I used a wrapper function to avoid having to modify all of my handler functions:
domainWrapper = function(func) {
return function(req, res) {
try {
return func(req, res);
} catch (err) {
domain.active.emit('error', err);
}
}
}
Then changed this sort of thing:
app.get('/jobs', handlerFunc);
to this:
app.get('/jobs', domainWrapper(handlerFunc));

Custom Events in Node.js with Express framework

So, I'd like to know how to create custom events in node.js, and I'm hitting a wall. I'm pretty sure I'm misunderstanding something about how express works and how node.js events work.
https://creativespace.nodejitsu.com That's the app.
When a user creates a new "activity" (something that will happen many times) they send a POST request. Then within my route, if that POST succeeds I'd like to emit an event, that tells socket.io to create a new namespace for that activity.
In my route file:
var eventEmitter = require('events').EventEmitter;
// Tell socket.io about the new space.
eventEmitter.emit('new activity', {activityId: body.id});
And socket.io:
// When someone creates a new activity
eventEmitter.on('new activity', function (data) { // this gives and error
var newActivity = '/activity?' + data.activityId;
io.of(newActivity).on('connection', function (socket) {
// Socket.io code for an activity
});
});
So the error I get is CANNOT CALL METHOD ON OF UNDEFINED and it refers to what would be line 2 in the socket.io above. I think I'm messing up my requires, maybe...or I'm not quite understanding how events work.
Any help, even a reference to good reading on Node.js events would rock!
Thanks!!!
If using express you can also just listen for event on the express 'app' which inherits from EventEmitter. For example:
res.app.on("myEvent", function)
and emit to it like
res.app.emit("myEvent", data)
You should treat EventEmitter as a class you can inherit from. Try this:
function MyEmitter () {
events.EventEmitter.call(this);
}
util.inherits(MyEmitter, events.EventEmitter);
Now you can use your class to listen and emit events:
var e = new MyEmitter;
e.on("test", function (m) { console.log(m); });
e.emit("test", "Hello World!");

Prevent Sails.js from handling errors

I have a Node.js (v5.6.0, npm: v3.7.1) app running with Sails.js (v0.12.0).
When I execute this code in app.js:
process.on('uncaughtException', err => {
//Do something
});
throw new Error();
It handles my error.
The problem is, after I load Sails, I can't catch errors with this method at all.
For example, throwing an error from bootstrap.js will not be caught by the above code and I get this message in my console:
error: Bootstrap encountered an error: (see below)
error: Error: asdf
at Object.module.exports.bootstrap.process.on.process.on.process.on.sails.async.series.callback [as bootstrap]
(c:\path\to\project\config\bootstrap
.js:41:8)
at Sails.runBootstrap (c:\path\to\project\node_modules\sails\lib\app\private\bootstrap.js:44:25)
at Sails.wrapper [as runBootstrap] (c:\path\to\project\node_modules\sails\node_modules\lodash\index.js:3095:19)
at Sails.initialize (c:\path\to\project\node_modules\sails\lib\app\private\initialize.js:54:9)
at wrapper (c:\path\to\project\node_modules\sails\node_modules\lodash\index.js:3095:19)
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:713:13
at iterate (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:262:13)
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:274:29
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:44:16
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:718:17
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:167:37
at module.exports (c:\path\to\project\node_modules\sails\lib\app\load.js:184:13)
at _toString (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:52:16)
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:548:17
at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:542:17
at _arrayEach (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:85:13) [Error: asdf]
I also tried to move the above code in bootstrap.js without any luck.
How can I handle any error with Sails project?
Thanks in advance!
For whom will come here and looks for full code, I'm posting my full code and explanation, based on #sgress454 answer:
Sails is a Web Framework that wraps your code to a web application, so it can't be never down, therefore-Sails try to handle all the errors by itself, and notify the user with 500 if needed, and continue to run the web application.
Sails app is divided into 2 steps:
Before Lifting-The web application isn't accessible by anyone:
If Sails got exception, it will quit the app, and call the lift callback with an error argument.
After Lifting-The web application is accessible:
If Sails got exception, it will quit the app, and call the lift callback with an error argument.
If Sails got exception while running the web application(after lifting), there's 2 options:
Exception inside a controller action itself:
Sails will catch this error, and respond to the user with 500.
Exception wherever else:
Sails wouldn't catch this error, and an uncaughtException will be thrown.
To handle all the above case we need to do the following:
First we want to create a global function so we can call it from wherever we are in the code:
ES 2015:
//app.js
global.handleErrors = err => {
//do something
}
ES 5.1(and before):
//app.js
global.handleErrors = function(err) {
//do something
}
Now we want to handle all uncaughtException's events:
//app.js
process.on('uncaughtException', handleErrors);
We can add some other events ex.:
//app.js
process.on('unhandledRejection', handleErrors);
process.on('rejectionHandled', handleErrors);
process.on('SIGINT', handleErrors);
To catch exceptions that happens in the lifting process we need to provide a callback to sails.lift function, and if the callback is called with an error we need to call the handleErrors function that we created:
ES 2015:
//app.js
sails.lift(rc('sails'), err => {
if (err) {
handleErrors(err);
}
});
ES 5.1(and before):
//app.js
sails.lift(rc('sails'), function(err) {
if (err) {
handleErrors(err);
}
});
And we want to handle exceptions in controllers that Sails catches and responded with 500:
//api/responses/serverError.js
module.exports = function serverError(data, options) {
handleErrors(data);
//lot of Sails things
};
In this way all the errors eventually will be hit the handleErrors function, so we can do there whatever we want with the error, ex. log to file, log to log management tool, send email to admin etc.
The code you posted will do exactly what it says: handle uncaught exceptions. Sails handles errors that occur during its initialization so it can attempt to exit gracefully, and attempts to handler errors that occur when processing requests so it can respond gracefully (with an error page) instead of crashing the server.
To handle errors that occur during the initialization process, provide a second argument--an error handling function--to .lift() in your app.js file:
sails.lift(rc('sails'), function handleLiftError(err, sailsInstance) {
if (err) {
console.log("Error occurred during sails.lift: ", err);
}
});
You can still leave your process.on('uncaughtException'),... code in to handle fatal errors that pop up as the app is running. For instance, if you had the following in a controller action:
myAction: function (req, res) {
throw new Error('foo!);
}
then Sails would catch that error for you and just respond with the 500 error page. But if you had:
myAction: function (req, res) {
setTimeout(function(){throw new Error('foo!);}
}
Sails would not catch it at all--but your process.on handler would (provided you started Sails with node app.js!)

Resources