@ -26,14 +26,15 @@ var common = require('../common');
var assert = require ( 'assert' ) ;
var assert = require ( 'assert' ) ;
var domain = require ( 'domain' ) ;
var domain = require ( 'domain' ) ;
var events = require ( 'events' ) ;
var events = require ( 'events' ) ;
var fs = require ( 'fs' ) ;
var caught = 0 ;
var caught = 0 ;
var expectCaught = 8 ;
var expectCaught = 0 ;
var d = new domain . Domain ( ) ;
var d = new domain . Domain ( ) ;
var e = new events . EventEmitter ( ) ;
var e = new events . EventEmitter ( ) ;
d . on ( 'error' , function ( er ) {
d . on ( 'error' , function ( er ) {
console . error ( 'caught' , er ) ;
console . error ( 'caught' , er && ( er . message || er ) ) ;
var er_message = er . message ;
var er_message = er . message ;
var er_path = er . path
var er_path = er . path
@ -110,24 +111,58 @@ d.on('error', function(er) {
break ;
break ;
default :
default :
console . error ( 'unexpected error, throwing %j' , er . message ) ;
console . error ( 'unexpected error, throwing %j' , er . message || er ) ;
throw er ;
throw er ;
}
}
caught ++ ;
caught ++ ;
} ) ;
} ) ;
process . on ( 'exit' , function ( ) {
process . on ( 'exit' , function ( ) {
console . error ( 'exit' ) ;
console . error ( 'exit' , caught , expectCaught ) ;
assert . equal ( caught , expectCaught ) ;
assert . equal ( caught , expectCaught , 'caught the expected number of errors' ) ;
console . log ( 'ok' ) ;
console . log ( 'ok' ) ;
} ) ;
} ) ;
// catch thrown errors no matter how many times we enter the event loop
// this only uses implicit binding, except for the first function
// passed to d.run(). The rest are implicitly bound by virtue of being
// set up while in the scope of the d domain.
d . run ( function ( ) {
process . nextTick ( function ( ) {
var i = setInterval ( function ( ) {
clearInterval ( i ) ;
setTimeout ( function ( ) {
fs . stat ( 'this file does not exist' , function ( er , stat ) {
// uh oh! stat isn't set!
// pretty common error.
console . log ( stat . isDirectory ( ) ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
expectCaught ++ ;
// implicit addition of a timer created within a domain-bound context.
d . run ( function ( ) {
setTimeout ( function ( ) {
throw new Error ( 'implicit timer' ) ;
} ) ;
} ) ;
expectCaught ++ ;
// Event emitters added to the domain have their errors routed.
// Event emitters added to the domain have their errors routed.
d . add ( e ) ;
d . add ( e ) ;
e . emit ( 'error' , new Error ( 'emitted' ) ) ;
e . emit ( 'error' , new Error ( 'emitted' ) ) ;
expectCaught ++ ;
@ -141,6 +176,9 @@ function fn(er) {
var bound = d . intercept ( fn ) ;
var bound = d . intercept ( fn ) ;
bound ( new Error ( 'bound' ) ) ;
bound ( new Error ( 'bound' ) ) ;
expectCaught ++ ;
// intercepted should never pass first argument to callback
// intercepted should never pass first argument to callback
function fn2 ( data ) {
function fn2 ( data ) {
@ -169,36 +207,16 @@ function thrower() {
throw new Error ( 'thrown' ) ;
throw new Error ( 'thrown' ) ;
}
}
setTimeout ( d . bind ( thrower ) , 100 ) ;
setTimeout ( d . bind ( thrower ) , 100 ) ;
expectCaught ++ ;
// Pass an intercepted function to an fs operation that fails.
// Pass an intercepted function to an fs operation that fails.
var fs = require ( 'fs' ) ;
fs . open ( 'this file does not exist' , 'r' , d . intercept ( function ( er ) {
fs . open ( 'this file does not exist' , 'r' , d . intercept ( function ( er ) {
console . error ( 'should not get here!' , er ) ;
console . error ( 'should not get here!' , er ) ;
throw new Error ( 'should not get here!' ) ;
throw new Error ( 'should not get here!' ) ;
} , true ) ) ;
} , true ) ) ;
expectCaught ++ ;
// catch thrown errors no matter how many times we enter the event loop
// this only uses implicit binding, except for the first function
// passed to d.run(). The rest are implicitly bound by virtue of being
// set up while in the scope of the d domain.
d . run ( function ( ) {
process . nextTick ( function ( ) {
var i = setInterval ( function ( ) {
clearInterval ( i ) ;
setTimeout ( function ( ) {
fs . stat ( 'this file does not exist' , function ( er , stat ) {
// uh oh! stat isn't set!
// pretty common error.
console . log ( stat . isDirectory ( ) ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
@ -213,16 +231,9 @@ setTimeout(function() {
// escape from the domain, but implicit is still bound to it.
// escape from the domain, but implicit is still bound to it.
implicit . emit ( 'error' , new Error ( 'implicit' ) ) ;
implicit . emit ( 'error' , new Error ( 'implicit' ) ) ;
} , 10 ) ;
} , 10 ) ;
expectCaught ++ ;
// implicit addition of a timer created within a domain-bound context.
d . run ( function ( ) {
setTimeout ( function ( ) {
throw new Error ( 'implicit timer' ) ;
} ) ;
} ) ;
var result = d . run ( function ( ) {
var result = d . run ( function ( ) {
return 'return value' ;
return 'return value' ;
} ) ;
} ) ;
@ -231,3 +242,4 @@ assert.equal(result, 'return value');
var fst = fs . createReadStream ( 'stream for nonexistent file' )
var fst = fs . createReadStream ( 'stream for nonexistent file' )
d . add ( fst )
d . add ( fst )
expectCaught ++ ;