the moment due to a bug; use +emitSuccess+ instead.)
+promise.emitError(arg1, arg2, ...)+ ::
-Emits the +"error"+ event.
+Emits the +"error"+ event. If a no error handler is attached to the promise
+between +promise.emitError()+ and +process.nextTick()+, an exception is
+thrown.
++
+To explain the exception behavior, assume you have a "computeQuestion"
+function as follows:
++
+----------------------------------------
+var events = require('events');
+function computeQuestion(answer) {
+ var promise = new events.Promise();
+ if (answer !== 42) {
+ promise.emitError('wrong answer');
+ return promise;
+ }
+ // compute the question for 42
+
+ return promise;
+}
+----------------------------------------
++
+You can stop an exception to be thrown here by attaching an errback handler
+right away (in the same event loop tick) like this:
++
+----------------------------------------
+computeQuestion(23).addErrback(function() {
+ // No exception will be thrown
+});
+----------------------------------------
++
+However, if you try to attach the error handler in a later tick, the promise
+will already have thrown an exception:
++
+----------------------------------------
+var promise = computeQuestion(23);
+setTimeout(function() {
+ promise.addErrback(function() {
+ // This will never execute, the promise already threw an exception
+ });
+}, 1000);
+----------------------------------------
+promise.timeout(timeout = undefined)+ ::
If the +timeout+ parameter is provided, the promise will emit an +"error"+
this._values = Array.prototype.slice.call(arguments);
this.emit.apply(this, ['error'].concat(this._values));
+
+ if (this.listeners('error').length == 0) {
+ var self = this;
+ process.nextTick(function() {
+ if (self.listeners('error').length == 0) {
+ throw new Error('Unhandled emitError: '+JSON.stringify(self._values));
+ }
+ });
+ }
};
exports.Promise.prototype.addCallback = function (listener) {
- if (!this.hasFired) {
- return this.addListener("success", listener);
+ if (this.hasFired) {
+ return listener.apply(this, this._values);
}
- listener.apply(this, this._values);
- return this;
+ return this.addListener("success", listener);
};
exports.Promise.prototype.addErrback = function (listener) {
- if (!this.hasFired) {
- return this.addListener("error", listener);
+ if (this.hasFired) {
+ listener.apply(this, this._values);
}
- listener.apply(this, this._values);
- return this;
+ return this.addListener("error", listener);
};
/* Poor Man's coroutines */
var loadPromise = new events.Promise();
process.mainModule.load(process.ARGV[1], loadPromise);
-loadPromise.addErrback(function(e) {
- throw e;
-});
-
// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
// there are no watchers on the loop (except for the ones that were
a2: 1,
b1: 1,
b2: 1,
+ c1: 1,
+ d1: 1,
};
// Test regular & late callback binding
expectedCallbacks.b2--;
});
+// Test late errback binding
+var c = new Promise();
+c.emitError(TEST_VALUE);
+c.addErrback(function(value) {
+ assert.equal(TEST_VALUE, value);
+ expectedCallbacks.c1--;
+});
+
+// Test errback exceptions
+var d = new Promise();
+d.emitError(TEST_VALUE);
+
+process.addListener('uncaughtException', function(e) {
+ if (e.name === "AssertionError") {
+ throw e;
+ }
+
+ expectedCallbacks.d1--;
+ assert.ok(e.message.match(/unhandled emitError/i));
+});
+
process.addListener('exit', function() {
for (var name in expectedCallbacks) {
var count = expectedCallbacks[name];