From 9a3d5f5bbddc2dff51071b6637517cbb7c860e6c Mon Sep 17 00:00:00 2001 From: James Padolsey Date: Sun, 15 Jan 2017 16:12:39 +0000 Subject: [PATCH 1/2] Avoid Error cloning error in Worker promise/rejection case - See #44 - Specifically pass message/stack and then catch on the other side --- src/contexts/BrowserWorker.js | 14 ++++++++++++++ test/operative.iframe.spec.js | 16 ++++++++++++++++ test/operative.spec.js | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/contexts/BrowserWorker.js b/src/contexts/BrowserWorker.js index ce493bf..6554b0d 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,17 @@ function workerBoilerScript() { return def; } function reject(r, transfers) { + if (r instanceof Error) { + postMessage({ + cmd: 'deferred_reject_error', + token: data.token, + error: { + message: r.message, + stack: r.stack + } + }); + 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..2a0a5fe 100644 --- a/test/operative.spec.js +++ b/test/operative.spec.js @@ -107,6 +107,22 @@ 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) { + console.log(err); + expect(err.message).to.equal('foo 789'); // pass + done(); + }); + }); + }); }); }); From a4dff924fdb87288fcb5c975c132218085be0f3d Mon Sep 17 00:00:00 2001 From: James Padolsey Date: Wed, 18 Jan 2017 08:26:33 +0000 Subject: [PATCH 2/2] Ensure we grab all props off native Error objs --- src/contexts/BrowserWorker.js | 17 +++++++++++++---- test/operative.spec.js | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/contexts/BrowserWorker.js b/src/contexts/BrowserWorker.js index 6554b0d..541035d 100644 --- a/src/contexts/BrowserWorker.js +++ b/src/contexts/BrowserWorker.js @@ -279,13 +279,22 @@ function workerBoilerScript() { } 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: { - message: r.message, - stack: r.stack - } + error: cloneableError }); return; } diff --git a/test/operative.spec.js b/test/operative.spec.js index 2a0a5fe..c0c420e 100644 --- a/test/operative.spec.js +++ b/test/operative.spec.js @@ -117,11 +117,28 @@ describe('Operative (worker Context)', function() { expect(true).to.be.false; // fail done(); }).catch(function(err) { - console.log(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(); + }); + }); + }); }); }); });