Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Nested domains failing #4733

Closed
CrabBot opened this issue Feb 9, 2013 · 3 comments
Closed

Nested domains failing #4733

CrabBot opened this issue Feb 9, 2013 · 3 comments
Labels

Comments

@CrabBot
Copy link

CrabBot commented Feb 9, 2013

The issue with domain._stack may be a red herring and by design, though it seems to be the issue. Either way, it does not seem that this test case should fail.

var domain = require('domain')
var assert = require('assert')
var count = 0

var d1 = domain.create()
d1.run(function () {
  process.nextTick(function() {
    var d2 = domain.create()
    d2.run(function () {
      process.nextTick(function() {
        // THE PROBLEM IS HERE
        // IT SEEMS domain._stack POPPED THE WRONG DOMAIN
        // WHICH RESULTS IN THE OUTER CATCH NEVER BEING CALLED
        // Should this pass?: assert.equal(domain._stack[0], d1)
        ++count
        throw new Error('test 2')
      }, 0)
    })
    d2.on('error', function(err) {
      console.log('inner')
      ;++count
      throw err;
    })
  }, 0)
})
d1.on('error', function(err) {
  console.log('outer')
  ++count
  assert.equal(err.message, 'test 2')
  assert.equal(count, 3)
  console.log('success!')
})
@bnoordhuis
Copy link
Member

That seems like the expected behavior when you throw from the error listener. From an example from the domains documentation:

    d.on('error', function(er) {
      // an error occurred somewhere.
      // if we throw it now, it will crash the program
      // with the normal line number and stack message.
    });

/cc @isaacs

@AlexeyKupershtokh
Copy link

And this expected behavior seems an issue.
I would draw an analogy with nested try-catch blocks. Functionality that domains currently provide seems incompatible with exception bubbling. Also throwing any errors (besides bubbling) from an error handler does't need to be fatal since domains stack is not empty.
Any chance for reappraising what should be expected behavior in this case?

@CrabBot
Copy link
Author

CrabBot commented Feb 11, 2013

FWIW, it looks like it's possible to mimic error bubbling through manual domain management (e.g., .run()). So it seems this is reasonable behavior given the flexibility of the other portions of the domain API. I could argue that requiring this manual domain management makes the domain API more cumbersome, but since it's easily abstracted, I think the additional flexibility is best.

For posterity, if anyone's looking to mimic domain error bubbling, here's my solution:

var domain = require('domain');

function trycatch (tryFn, catchFn) {
  var parentDomain = domain.active
    , d = domain.create()

  d.on('error', function onError(err) {
    run(parentDomain, function() {
      catchFn(err)
    })
  })

  run(d, tryFn)
}

function run(d, fn) {
  if (d && !d._disposed) {
    try {
      d.run(fn)
    } catch(e) {
      d.emit('error', e)
    }
  } else {
    fn()
  }
}

module.exports = trycatch

@CrabBot CrabBot closed this as completed Feb 11, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants