dorexx45
dorexx45

Reputation: 71

Nodejs error handling with domains and socket.io

I'm just starting using domains in nodejs for error management.

There's something I cant understand when I use them with socket.io.

That's my example code:

io.sockets.on('connection', function cb1(socket){
    socket.on('event', function cb2(data){
    });
});

I started putting all my code in the "run" method

domain.run(function(){
    io.sockets.on('connection', function cb1(socket){
        socket.on('event', function cb2(data){
        });
    });
});

But if an error happens in cb1 or cb2 it is not handled!

Then I used the bind methon on che cb1

domain.run(function(){
    io.sockets.on('connection', domain.bind(function cb1(socket){
        socket.on('event', function cb2(data){
        });
    }));
});

But if an error happens in cb2 it is not handled!

My question is: do I have to put a single "bind" on every callback? In the server and in the required files?

When I started studied the domains all the tutorials define them like the best solution to handle your errors in one single point!

Am I missing something?

Upvotes: 7

Views: 5035

Answers (4)

Matt Harrison
Matt Harrison

Reputation: 13567

What I do is create a new domain for each socket:

var Domain = require('domain');

...

io.sockets.on('connection', function (socket){

    d = domain.create();
    d.add(socket);

    d.on('error', function () {

        // You have access to the socket too in here, useful
    });

    socket.on('event', function (data){

        socket.on('event2', function (data){

            throw new Error('I will be caught!');
        });
    });
});

Why does this work?

Domain.prototype.add will add an existing event emitter to the domain. Meaning all new callbacks from events on that emitter will be implicitly bound to the domain.

Upvotes: 0

franzlorenzon
franzlorenzon

Reputation: 5943

Edit: Yes, you have to bind every callback.

Have a look on this screencast, it explains this problem: Node Tuts Episode VIII - Handling Errors Using Domains (he starts talking about this from 13:45).

If I have understood it correctly, if you don't emit or throw errors inside the callbacks, you have to explicitly bind them with .bind or .intercept. But in my own experience in callbacks this is not enough, and I have to bind every callback to the domain.

Upvotes: 0

dorexx45
dorexx45

Reputation: 41

(I'm dorexx45, I forgot the password)

I tried but it partially works.

If I create an object (es. mysql connection) inside the domain, the errors on that object are not handled!

domain.run(function(){
  var pool = mysql.createPool();
  var io = require('socket.io').listen(80);
  io.sockets.on('connection', function cb1(socket){
    socket.on('event', function cb2(data){
       pool.something();
   });
  }));
});

If something happens in pool.something(), like bad query syntax or wrong connection data, the error are not "catched" by domain.run!

Upvotes: 0

dvishal
dvishal

Reputation: 166

If you create socket in the scope of domain then all events in that socket object that throws error will be caught by domain.

domain.run(function(){
  var io = require('socket.io').listen(80);
  io.sockets.on('connection', function cb1(socket){
    socket.on('event', function cb2(data){
   });
  }));
});

Try this.

Upvotes: 0

Related Questions