diff --git a/src/contexts/BrowserWorker.js b/src/contexts/BrowserWorker.js index ce493bf..541035d 100644 --- a/src/contexts/BrowserWorker.js +++ b/src/contexts/BrowserWorker.js @@ -86,6 +86,9 @@ case 'console': window.console && window.console[data.method].apply(window.console, data.args); break; + case 'deferred_reject_error': + this.deferreds[data.token].reject(data.error); + break; case 'result': var callback = this.callbacks[data.token]; @@ -275,6 +278,26 @@ function workerBoilerScript() { return def; } function reject(r, transfers) { + if (r instanceof Error) { + // Create an error object that can be cloned: (See #44/#45): + var cloneableError = { + message: r.message, + stack: r.stack, + name: r.name, + code: r.code + }; + for (var i in r) { + if (r.hasOwnProperty(i)) { + cloneableError[i] = r[i]; + } + } + postMessage({ + cmd: 'deferred_reject_error', + token: data.token, + error: cloneableError + }); + return; + } returnResult({ isDeferred: true, action: 'reject', diff --git a/test/operative.iframe.spec.js b/test/operative.iframe.spec.js index a983764..660b8bf 100644 --- a/test/operative.iframe.spec.js +++ b/test/operative.iframe.spec.js @@ -97,6 +97,22 @@ describe('Operative (forced iframe context)', function() { }); }); }); + describe('Rejecting with an error', function() { + it('Should reject correctly', function(done) { + var op = operative(function() { + var deferred = this.deferred(); + deferred.reject(new Error('foo 789')); + }); + op().then(function() { + expect(true).to.be.false; // fail + done(); + }).catch(function(err) { + console.log(err); + expect(err.message).to.equal('foo 789'); // pass + done(); + }); + }); + }); }); }); diff --git a/test/operative.spec.js b/test/operative.spec.js index d2949f0..c0c420e 100644 --- a/test/operative.spec.js +++ b/test/operative.spec.js @@ -107,6 +107,39 @@ describe('Operative (worker Context)', function() { }); }); }); + describe('Rejecting with an error', function() { + it('Should reject correctly', function(done) { + var op = operative(function() { + var deferred = this.deferred(); + deferred.reject(new Error('foo 789')); + }); + op().then(function() { + expect(true).to.be.false; // fail + done(); + }).catch(function(err) { + expect(err.message).to.equal('foo 789'); // pass + done(); + }); + }); + describe('With additional props', function() { + it('Should reject correctly and be received with props', function(done) { + var op = operative(function() { + var deferred = this.deferred(); + var error = new Error('foo'); + error.custom = 123; + deferred.reject(error); + }); + op().then(function() { + expect(true).to.be.false; // fail + done(); + }).catch(function(err) { + expect(err.message).to.equal('foo'); + expect(err.custom).to.equal(123); + done(); + }); + }); + }); + }); }); });