| @@ -0,0 +1,156 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var dns = require('dns'); | ||
| var fs = require('fs'); | ||
| var net = require('net'); | ||
|
|
||
| var errorMsgs = []; | ||
| var caught = 0; | ||
| var expectCaught = 0; | ||
| var exitCbRan = false; | ||
|
|
||
| function asyncL() { } | ||
|
|
||
| var callbacksObj = { | ||
| error: function(value, er) { | ||
| var idx = errorMsgs.indexOf(er.message); | ||
|
|
||
| caught++; | ||
|
|
||
| if (-1 < idx) | ||
| errorMsgs.splice(idx, 1); | ||
| else | ||
| throw new Error('Message not found: ' + er.message); | ||
|
|
||
| return true; | ||
| } | ||
| }; | ||
|
|
||
| var listener = process.createAsyncListener(asyncL, callbacksObj); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // Just in case. | ||
| process.removeAsyncListener(listener); | ||
|
|
||
| if (code > 0) | ||
| return; | ||
|
|
||
| assert.ok(!exitCbRan); | ||
| exitCbRan = true; | ||
|
|
||
| if (errorMsgs.length > 0) | ||
| throw new Error('Errors not fired: ' + errorMsgs); | ||
|
|
||
| assert.equal(caught, expectCaught); | ||
| process._rawDebug('ok'); | ||
| }); | ||
|
|
||
|
|
||
| // Simple cases | ||
| errorMsgs.push('setTimeout - simple'); | ||
| errorMsgs.push('setImmediate - simple'); | ||
| errorMsgs.push('setInterval - simple'); | ||
| setTimeout(function() { | ||
| throw new Error('setTimeout - simple'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
|
|
||
| setImmediate(function() { | ||
| throw new Error('setImmediate - simple'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
|
|
||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| throw new Error('setInterval - simple'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
|
|
||
|
|
||
| // Deeply nested | ||
| errorMsgs.push('setInterval - nested'); | ||
| errorMsgs.push('setImmediate - nested'); | ||
| errorMsgs.push('setTimeout - nested'); | ||
| setTimeout(function() { | ||
| setImmediate(function() { | ||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| throw new Error('setInterval - nested'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
| throw new Error('setImmediate - nested'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
| throw new Error('setTimeout - nested'); | ||
| }).addAsyncListener(listener); | ||
| expectCaught++; | ||
|
|
||
|
|
||
| // Net | ||
| var iter = 3; | ||
| for (var i = 0; i < iter; i++) { | ||
| errorMsgs.push('net - server connection'); | ||
| errorMsgs.push('net - client data'); | ||
| errorMsgs.push('net - server data'); | ||
| } | ||
| errorMsgs.push('net - server closed'); | ||
|
|
||
| var server = net.createServer(function(c) { | ||
| c._handle.addAsyncListener(listener); | ||
|
|
||
| c.on('data', function() { | ||
| if (0 === --iter) { | ||
| server.close(function() { | ||
| throw new Error('net - server closed'); | ||
| }); | ||
| expectCaught++; | ||
| } | ||
| throw new Error('net - server data'); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| c.end('bye'); | ||
| throw new Error('net - server connection'); | ||
| }); | ||
| expectCaught += iter; | ||
|
|
||
| server.listen(common.PORT, function() { | ||
| // Test adding the async listener after server creation. Though it | ||
| // won't catch errors that originate synchronously from this point. | ||
| server._handle.addAsyncListener(listener); | ||
| for (var i = 0; i < iter; i++) | ||
| clientConnect(); | ||
| }); | ||
|
|
||
| function clientConnect() { | ||
| var client = net.connect(common.PORT, function() { | ||
| client._handle.addAsyncListener(listener); | ||
| }); | ||
|
|
||
| client.on('data', function() { | ||
| client.end('see ya'); | ||
| throw new Error('net - client data'); | ||
| }); | ||
| expectCaught++; | ||
| } |
| @@ -0,0 +1,68 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| var active = null; | ||
| var cntr = 0; | ||
|
|
||
| function onAsync0() { | ||
| return 0; | ||
| } | ||
|
|
||
| function onAsync1() { | ||
| return 1; | ||
| } | ||
|
|
||
| var results = []; | ||
| var asyncNoHandleError = { | ||
| error: function(stor) { | ||
| results.push(stor); | ||
| return true; | ||
| } | ||
| }; | ||
|
|
||
| var listeners = [ | ||
| process.addAsyncListener(onAsync0, asyncNoHandleError), | ||
| process.addAsyncListener(onAsync1, asyncNoHandleError) | ||
| ]; | ||
|
|
||
| process.nextTick(function() { | ||
| throw new Error(); | ||
| }); | ||
|
|
||
| process.removeAsyncListener(listeners[0]); | ||
| process.removeAsyncListener(listeners[1]); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // Handling of errors should propagate to all listeners. | ||
| assert.equal(results[0], 0); | ||
| assert.equal(results[1], 1); | ||
| assert.equal(results.length, 2); | ||
|
|
||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,66 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| function onAsync() {} | ||
|
|
||
| var results = []; | ||
| var asyncNoHandleError = { | ||
| error: function(stor) { | ||
| results.push(1); | ||
| } | ||
| }; | ||
|
|
||
| var asyncHandleError = { | ||
| error: function(stor) { | ||
| results.push(0); | ||
| return true; | ||
| } | ||
| }; | ||
|
|
||
| var listeners = [ | ||
| process.addAsyncListener(onAsync, asyncHandleError), | ||
| process.addAsyncListener(onAsync, asyncNoHandleError) | ||
| ]; | ||
|
|
||
| // Even if an error handler returns true, both should fire. | ||
| process.nextTick(function() { | ||
| throw new Error(); | ||
| }); | ||
|
|
||
| process.removeAsyncListener(listeners[0]); | ||
| process.removeAsyncListener(listeners[1]); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // Mixed handling of errors should propagate to all listeners. | ||
| assert.equal(results[0], 0); | ||
| assert.equal(results[1], 1); | ||
| assert.equal(results.length, 2); | ||
|
|
||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,71 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| function onAsync0() { | ||
| return 0; | ||
| } | ||
|
|
||
| function onAsync1() { | ||
| return 1; | ||
| } | ||
|
|
||
| var results = []; | ||
| var asyncNoHandleError = { | ||
| error: function(stor) { | ||
| results.push(stor); | ||
| } | ||
| }; | ||
|
|
||
| var listeners = [ | ||
| process.addAsyncListener(onAsync0, asyncNoHandleError), | ||
| process.addAsyncListener(onAsync1, asyncNoHandleError) | ||
| ]; | ||
|
|
||
| var uncaughtFired = false; | ||
| process.on('uncaughtException', function() { | ||
| uncaughtFired = true; | ||
|
|
||
| // Unhandled errors should propagate to all listeners. | ||
| assert.equal(results[0], 0); | ||
| assert.equal(results[1], 1); | ||
| assert.equal(results.length, 2); | ||
| }); | ||
|
|
||
| process.nextTick(function() { | ||
| throw new Error(); | ||
| }); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // Need to remove the async listeners or tests will always pass | ||
| for (var i = 0; i < listeners.length; i++) | ||
| process.removeAsyncListener(listeners[i]); | ||
|
|
||
| assert.ok(uncaughtFired); | ||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,62 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| var once = 0; | ||
| function onAsync0() { } | ||
|
|
||
| var results = []; | ||
| var handlers = { | ||
| after: function() { | ||
| throw 1; | ||
| }, | ||
| error: function(stor, err) { | ||
| // Error handler must be called exactly *once*. | ||
| once++; | ||
| assert.equal(err, 1); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| var key = process.addAsyncListener(onAsync0, handlers); | ||
|
|
||
| var uncaughtFired = false; | ||
| process.on('uncaughtException', function(err) { | ||
| uncaughtFired = true; | ||
|
|
||
| assert.equal(once, 1); | ||
| }); | ||
|
|
||
| process.nextTick(function() { }); | ||
|
|
||
| process.removeAsyncListener(key); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| assert.ok(uncaughtFired); | ||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,81 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| var once = 0; | ||
| function onAsync0() { } | ||
| function onAsync1() { } | ||
|
|
||
| var results = []; | ||
| var handlers = { | ||
| before: function() { | ||
| throw 1; | ||
| }, | ||
| error: function(stor, err) { | ||
| // Must catch error thrown in before callback. | ||
| assert.equal(err, 1); | ||
| once++; | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| var handlers1 = { | ||
| before: function() { | ||
| throw 2; | ||
| }, | ||
| error: function(stor, err) { | ||
| // Must catch *other* handlers throw by error callback. | ||
| assert.equal(err, 1); | ||
| once++; | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| var listeners = [ | ||
| process.addAsyncListener(onAsync0, handlers), | ||
| process.addAsyncListener(onAsync1, handlers1) | ||
| ]; | ||
|
|
||
| var uncaughtFired = false; | ||
| process.on('uncaughtException', function(err) { | ||
| uncaughtFired = true; | ||
|
|
||
| // Both error handlers must fire. | ||
| assert.equal(once, 2); | ||
| }); | ||
|
|
||
| process.nextTick(function() { }); | ||
|
|
||
| for (var i = 0; i < listeners.length; i++) | ||
| process.removeAsyncListener(listeners[i]); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
| // Make sure uncaughtException actually fired. | ||
| assert.ok(uncaughtFired); | ||
| console.log('ok'); | ||
| }); | ||
|
|
| @@ -0,0 +1,64 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| var once = 0; | ||
| function onAsync0() {} | ||
|
|
||
| var results = []; | ||
| var handlers = { | ||
| before: function() { | ||
| throw 1; | ||
| }, | ||
| error: function(stor, err) { | ||
| // Error handler must be called exactly *once*. | ||
| once++; | ||
| assert.equal(err, 1); | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| var key = process.addAsyncListener(onAsync0, handlers); | ||
|
|
||
| var uncaughtFired = false; | ||
| process.on('uncaughtException', function(err) { | ||
| uncaughtFired = true; | ||
|
|
||
| // Process should propagate error regardless of handlers return value. | ||
| assert.equal(once, 1); | ||
| }); | ||
|
|
||
| process.nextTick(function() { }); | ||
|
|
||
| process.removeAsyncListener(key); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // Make sure that the uncaughtException actually fired. | ||
| assert.ok(uncaughtFired); | ||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,78 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var spawn = require('child_process').spawn; | ||
|
|
||
| var checkStr = 'WRITTEN ON EXIT\n'; | ||
|
|
||
| if (process.argv[2] === 'child') | ||
| runChild(); | ||
| else | ||
| runParent(); | ||
|
|
||
|
|
||
| function runChild() { | ||
| var cntr = 0; | ||
|
|
||
| var key = process.addAsyncListener(function() { }, { | ||
| error: function onError() { | ||
| cntr++; | ||
| throw new Error('onError'); | ||
| } | ||
| }); | ||
|
|
||
| process.on('unhandledException', function() { | ||
| // Throwing in 'error' should bypass unhandledException. | ||
| process.exit(2); | ||
| }); | ||
|
|
||
| process.on('exit', function() { | ||
| // Make sure that we can still write out to stderr even when the | ||
| // process dies. | ||
| process._rawDebug(checkStr); | ||
| }); | ||
|
|
||
| process.nextTick(function() { | ||
| throw new Error('nextTick'); | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| function runParent() { | ||
| var childStr = ''; | ||
| var child = spawn(process.execPath, [__filename, 'child']); | ||
| child.stderr.on('data', function(chunk) { | ||
| childStr += chunk.toString(); | ||
| }); | ||
|
|
||
| child.on('exit', function(code) { | ||
| // This is thrown when Node throws from _fatalException. | ||
| assert.equal(code, 7); | ||
| }); | ||
|
|
||
| process.on('exit', function() { | ||
| assert.notEqual(childStr.indexOf(checkStr), -1); | ||
| console.log('ok'); | ||
| }); | ||
| } | ||
|
|
| @@ -0,0 +1,258 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var dns = require('dns'); | ||
| var fs = require('fs'); | ||
| var net = require('net'); | ||
|
|
||
| var addListener = process.addAsyncListener; | ||
| var removeListener = process.removeAsyncListener; | ||
| var errorMsgs = []; | ||
| var currentMsg = ''; | ||
| var caught = 0; | ||
| var expectCaught = 0; | ||
| var exitCbRan = false; | ||
|
|
||
| function asyncL() { } | ||
|
|
||
| var callbacksObj = { | ||
| error: function(value, er) { | ||
| var idx = errorMsgs.indexOf(er.message); | ||
|
|
||
| caught++; | ||
|
|
||
| if (-1 < idx) | ||
| errorMsgs.splice(idx, 1); | ||
|
|
||
| return currentMsg === er.message; | ||
| } | ||
| }; | ||
|
|
||
| var listener = process.createAsyncListener(asyncL, callbacksObj); | ||
|
|
||
| process.on('exit', function(code) { | ||
| removeListener(listener); | ||
|
|
||
| // Something else went wrong, no need to further check. | ||
| if (code > 0) | ||
| return; | ||
|
|
||
| // Make sure the exit callback only runs once. | ||
| assert.ok(!exitCbRan); | ||
| exitCbRan = true; | ||
|
|
||
| // Check if any error messages weren't removed from the msg queue. | ||
| if (errorMsgs.length > 0) | ||
| throw new Error('Errors not fired: ' + errorMsgs); | ||
|
|
||
| assert.equal(caught, expectCaught, 'caught all expected errors'); | ||
| process._rawDebug('ok'); | ||
| }); | ||
|
|
||
|
|
||
| // Catch synchronous throws | ||
| errorMsgs.push('sync throw'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| expectCaught++; | ||
| currentMsg = 'sync throw'; | ||
| throw new Error(currentMsg); | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Simple cases | ||
| errorMsgs.push('setTimeout - simple'); | ||
| errorMsgs.push('setImmediate - simple'); | ||
| errorMsgs.push('setInterval - simple'); | ||
| errorMsgs.push('process.nextTick - simple'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| setTimeout(function() { | ||
| currentMsg = 'setTimeout - simple'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| setImmediate(function() { | ||
| currentMsg = 'setImmediate - simple'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| currentMsg = 'setInterval - simple'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| process.nextTick(function() { | ||
| currentMsg = 'process.nextTick - simple'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Deeply nested | ||
| errorMsgs.push('setInterval - nested'); | ||
| errorMsgs.push('setImmediate - nested'); | ||
| errorMsgs.push('process.nextTick - nested'); | ||
| errorMsgs.push('setTimeout2 - nested'); | ||
| errorMsgs.push('setTimeout - nested'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| setTimeout(function() { | ||
| process.nextTick(function() { | ||
| setImmediate(function() { | ||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| currentMsg = 'setInterval - nested'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| currentMsg = 'setImmediate - nested'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| currentMsg = 'process.nextTick - nested'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| setTimeout(function() { | ||
| currentMsg = 'setTimeout2 - nested'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| currentMsg = 'setTimeout - nested'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // FS | ||
| errorMsgs.push('fs - file does not exist'); | ||
| errorMsgs.push('fs - exists'); | ||
| errorMsgs.push('fs - realpath'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| fs.stat('does not exist', function(err, stats) { | ||
| currentMsg = 'fs - file does not exist'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| fs.exists('hi all', function(exists) { | ||
| currentMsg = 'fs - exists'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| fs.realpath('/some/path', function(err, resolved) { | ||
| currentMsg = 'fs - realpath'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Nested FS | ||
| errorMsgs.push('fs - nested file does not exist'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| setTimeout(function() { | ||
| setImmediate(function() { | ||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| process.nextTick(function() { | ||
| fs.stat('does not exist', function(err, stats) { | ||
| currentMsg = 'fs - nested file does not exist'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Net | ||
| errorMsgs.push('net - connection listener'); | ||
| errorMsgs.push('net - client connect'); | ||
| errorMsgs.push('net - server listening'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| var server = net.createServer(function(c) { | ||
| server.close(); | ||
| currentMsg = 'net - connection listener'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| server.listen(common.PORT, function() { | ||
| var client = net.connect(common.PORT, function() { | ||
| client.end(); | ||
| currentMsg = 'net - client connect'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
| currentMsg = 'net - server listening'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // DNS | ||
| errorMsgs.push('dns - lookup'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| dns.lookup('localhost', function() { | ||
| currentMsg = 'dns - lookup'; | ||
| throw new Error(currentMsg); | ||
| }); | ||
| expectCaught++; | ||
|
|
||
| removeListener(listener); | ||
| }); |
| @@ -0,0 +1,71 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| var addListener = process.addAsyncListener; | ||
| var removeListener = process.removeAsyncListener; | ||
| var caught = []; | ||
| var expect = []; | ||
|
|
||
| function asyncL(a) {} | ||
|
|
||
| var callbacksObj = { | ||
| error: function(value, er) { | ||
| process._rawDebug('caught', er.message); | ||
| caught.push(er.message); | ||
| return (expect.indexOf(er.message) !== -1); | ||
| } | ||
| }; | ||
|
|
||
| var listener = process.createAsyncListener(asyncL, callbacksObj); | ||
|
|
||
| process.on('exit', function(code) { | ||
| removeListener(listener); | ||
|
|
||
| if (code > 0) | ||
| return; | ||
|
|
||
| expect = expect.sort(); | ||
| caught = caught.sort(); | ||
|
|
||
| process._rawDebug('expect', expect); | ||
| process._rawDebug('caught', caught); | ||
| assert.deepEqual(caught, expect, 'caught all expected errors'); | ||
| process._rawDebug('ok'); | ||
| }); | ||
|
|
||
|
|
||
| expect.push('immediate simple a'); | ||
| expect.push('immediate simple b'); | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
| // Tests for a setImmediate specific bug encountered while implementing | ||
| // AsyncListeners. | ||
| setImmediate(function() { | ||
| throw new Error('immediate simple a'); | ||
| }); | ||
| setImmediate(function() { | ||
| throw new Error('immediate simple b'); | ||
| }); | ||
| removeListener(listener); | ||
| }); |
| @@ -0,0 +1,66 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var net = require('net'); | ||
|
|
||
|
|
||
| // TODO(trevnorris): Test has the flaw that it's not checking if the async | ||
| // flag has been removed on the class instance. Though currently there's | ||
| // no way to do that. | ||
| var listener = process.addAsyncListener(function() { }); | ||
|
|
||
|
|
||
| // Test timers | ||
|
|
||
| setImmediate(function() { | ||
| assert.equal(this._asyncQueue.length, 0); | ||
| }).removeAsyncListener(listener); | ||
|
|
||
| setTimeout(function() { | ||
| assert.equal(this._asyncQueue.length, 0); | ||
| }).removeAsyncListener(listener); | ||
|
|
||
| setInterval(function() { | ||
| clearInterval(this); | ||
| assert.equal(this._asyncQueue.length, 0); | ||
| }).removeAsyncListener(listener); | ||
|
|
||
|
|
||
| // Test net | ||
|
|
||
| var server = net.createServer(function(c) { | ||
| c._handle.removeAsyncListener(listener); | ||
| assert.equal(c._handle._asyncQueue.length, 0); | ||
| }); | ||
|
|
||
| server.listen(common.PORT, function() { | ||
| server._handle.removeAsyncListener(listener); | ||
| assert.equal(server._handle._asyncQueue.length, 0); | ||
|
|
||
| var client = net.connect(common.PORT, function() { | ||
| client._handle.removeAsyncListener(listener); | ||
| assert.equal(client._handle._asyncQueue.length, 0); | ||
| client.end(); | ||
| server.close(); | ||
| }); | ||
| }); |
| @@ -0,0 +1,54 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var set = 0; | ||
|
|
||
| function onAsync0() { } | ||
|
|
||
| var asyncNoHandleError = { | ||
| before: function() { | ||
| set++; | ||
| }, | ||
| after: function() { | ||
| set++; | ||
| } | ||
| } | ||
|
|
||
| var key = process.addAsyncListener(onAsync0, asyncNoHandleError); | ||
|
|
||
| process.removeAsyncListener(key); | ||
|
|
||
| process.nextTick(function() { }); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // The async handler should never be called. | ||
| assert.equal(set, 0); | ||
| console.log('ok'); | ||
| }); | ||
|
|
||
|
|
| @@ -0,0 +1,59 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| function onAsync0() { } | ||
|
|
||
| var set = 0; | ||
| var asyncNoHandleError = { | ||
| error: function() { | ||
| set++; | ||
| } | ||
| } | ||
|
|
||
| var key = process.addAsyncListener(onAsync0, asyncNoHandleError); | ||
|
|
||
| process.nextTick(function() { | ||
| throw 1; | ||
| }); | ||
|
|
||
| process.removeAsyncListener(key); | ||
|
|
||
| var uncaughtFired = false; | ||
| process.on('uncaughtException', function() { | ||
| uncaughtFired = true; | ||
|
|
||
| // Throwing should call the error handler once, then propagate to | ||
| // uncaughtException | ||
| assert.equal(set, 1); | ||
| }); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| assert.ok(uncaughtFired); | ||
| console.log('ok'); | ||
| }); |
| @@ -0,0 +1,54 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| function onAsync0() { } | ||
|
|
||
| var set = 0; | ||
| var asyncNoHandleError = { | ||
| before: function() { | ||
| set++; | ||
| }, | ||
| after: function() { | ||
| set++; | ||
| } | ||
| } | ||
|
|
||
| var key = process.addAsyncListener(onAsync0, asyncNoHandleError); | ||
|
|
||
| process.nextTick(function() { }); | ||
|
|
||
| process.removeAsyncListener(key); | ||
|
|
||
| process.on('exit', function(code) { | ||
| // If the exit code isn't ok then return early to throw the stack that | ||
| // caused the bad return code. | ||
| if (code !== 0) | ||
| return; | ||
|
|
||
| // Calling removeAsyncListener *after* a callback is scheduled | ||
| // should not affect the handler from responding to the callback. | ||
| assert.equal(set, 2); | ||
| console.log('ok'); | ||
| }); | ||
|
|
| @@ -0,0 +1,47 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
|
|
||
| // If there is an uncaughtException listener then the error thrown from | ||
| // "before" will be considered handled, thus calling setImmediate to | ||
| // finish execution of the nextTickQueue. This in turn will cause "before" | ||
| // to fire again, entering into an infinite loop. | ||
| // So the asyncQueue is cleared from the returned setImmediate in | ||
| // _fatalException to prevent this from happening. | ||
| var cntr = 0; | ||
|
|
||
|
|
||
| process.addAsyncListener(function() { }, { | ||
| before: function() { | ||
| if (++cntr > 1) { | ||
| // Can't throw since uncaughtException will also catch that. | ||
| process._rawDebug('Error: Multiple before callbacks called'); | ||
| process.exit(1); | ||
| } | ||
| throw new Error('before'); | ||
| } | ||
| }); | ||
|
|
||
| process.on('uncaughtException', function() { }); | ||
|
|
||
| process.nextTick(); |
| @@ -0,0 +1,185 @@ | ||
| // Copyright Joyent, Inc. and other Node contributors. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a | ||
| // copy of this software and associated documentation files (the | ||
| // "Software"), to deal in the Software without restriction, including | ||
| // without limitation the rights to use, copy, modify, merge, publish, | ||
| // distribute, sublicense, and/or sell copies of the Software, and to permit | ||
| // persons to whom the Software is furnished to do so, subject to the | ||
| // following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included | ||
| // in all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
| // USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
|
||
| var common = require('../common'); | ||
| var assert = require('assert'); | ||
| var net = require('net'); | ||
| var fs = require('fs'); | ||
| var dgram = require('dgram'); | ||
|
|
||
| var addListener = process.addAsyncListener; | ||
| var removeListener = process.removeAsyncListener; | ||
| var actualAsync = 0; | ||
| var expectAsync = 0; | ||
|
|
||
| function onAsync() { | ||
| actualAsync++; | ||
| } | ||
|
|
||
| var listener = process.createAsyncListener(onAsync); | ||
|
|
||
| process.on('exit', function() { | ||
| process._rawDebug('expected', expectAsync); | ||
| process._rawDebug('actual ', actualAsync); | ||
| // TODO(trevnorris): Not a great test. If one was missed, but others | ||
| // overflowed then the test would still pass. | ||
| assert.ok(actualAsync >= expectAsync); | ||
| }); | ||
|
|
||
|
|
||
| // Test listeners side-by-side | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| var b = setInterval(function() { | ||
| clearInterval(b); | ||
| }); | ||
| expectAsync++; | ||
|
|
||
| var c = setInterval(function() { | ||
| clearInterval(c); | ||
| }); | ||
| expectAsync++; | ||
|
|
||
| setTimeout(function() { }); | ||
| expectAsync++; | ||
|
|
||
| setTimeout(function() { }); | ||
| expectAsync++; | ||
|
|
||
| process.nextTick(function() { }); | ||
| expectAsync++; | ||
|
|
||
| process.nextTick(function() { }); | ||
| expectAsync++; | ||
|
|
||
| setImmediate(function() { }); | ||
| expectAsync++; | ||
|
|
||
| setImmediate(function() { }); | ||
| expectAsync++; | ||
|
|
||
| setTimeout(function() { }, 10); | ||
| expectAsync++; | ||
|
|
||
| setTimeout(function() { }, 10); | ||
| expectAsync++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Async listeners should propagate with nested callbacks | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
| var interval = 3; | ||
|
|
||
| process.nextTick(function() { | ||
| setTimeout(function() { | ||
| setImmediate(function() { | ||
| var i = setInterval(function() { | ||
| if (--interval <= 0) | ||
| clearInterval(i); | ||
| }); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
| process.nextTick(function() { | ||
| setImmediate(function() { | ||
| setTimeout(function() { }, 20); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Test triggers with two async listeners | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
| addListener(listener); | ||
|
|
||
| setTimeout(function() { | ||
| process.nextTick(function() { }); | ||
| expectAsync += 2; | ||
| }); | ||
| expectAsync += 2; | ||
|
|
||
| removeListener(listener); | ||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Test callbacks from fs I/O | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| fs.stat('something random', function(err, stat) { }); | ||
| expectAsync++; | ||
|
|
||
| setImmediate(function() { | ||
| fs.stat('random again', function(err, stat) { }); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Test net I/O | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| var server = net.createServer(function(c) { }); | ||
| expectAsync++; | ||
|
|
||
| server.listen(common.PORT, function() { | ||
| server.close(); | ||
| expectAsync++; | ||
| }); | ||
| expectAsync++; | ||
|
|
||
| removeListener(listener); | ||
| }); | ||
|
|
||
|
|
||
| // Test UDP | ||
| process.nextTick(function() { | ||
| addListener(listener); | ||
|
|
||
| var server = dgram.createSocket('udp4'); | ||
| expectAsync++; | ||
|
|
||
| server.bind(common.PORT); | ||
|
|
||
| server.close(); | ||
| expectAsync++; | ||
|
|
||
| removeListener(listener); | ||
| }); |