From e16ffc716788c8aef24b63b73a004ccbe37702ed Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Fri, 25 Aug 2017 06:20:59 -0700 Subject: [PATCH] =?UTF-8?q?[BUGFIX=20LTS]=20ensure=20=E2=80=9Cpause=20on?= =?UTF-8?q?=20exception=E2=80=9D=20pauses=20in=20the=20right=20place?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is quite common (like in ember-data’s tests) to not have a global onError handler in tests. But because of the previous state of code, we would still end up paused in the default dispatchError rather then where the actual error was thrown. This addresses the issue, but ensuring onErrorTarget.onerror returns undefined if no onError has been set --- packages/ember-metal/lib/error_handler.js | 6 ++ packages/ember-metal/lib/run_loop.js | 20 ++----- .../ember-metal/tests/error_handler_test.js | 56 +++++++++++++++++++ 3 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 packages/ember-metal/tests/error_handler_test.js diff --git a/packages/ember-metal/lib/error_handler.js b/packages/ember-metal/lib/error_handler.js index cc157167b89..a299c39c3b4 100644 --- a/packages/ember-metal/lib/error_handler.js +++ b/packages/ember-metal/lib/error_handler.js @@ -13,6 +13,12 @@ let getStack = error => { return stack; }; +export const onErrorTarget = { + get onerror() { + return dispatchOverride || getOnerror(); + } +}; + let onerror; // Ember.onerror getter export function getOnerror() { diff --git a/packages/ember-metal/lib/run_loop.js b/packages/ember-metal/lib/run_loop.js index 181ae44dcb7..5c5e81ad53f 100644 --- a/packages/ember-metal/lib/run_loop.js +++ b/packages/ember-metal/lib/run_loop.js @@ -1,8 +1,7 @@ import { GUID_KEY } from 'ember-utils'; import { assert, isTesting } from 'ember-debug'; import { - dispatchError, - setOnerror + onErrorTarget } from './error_handler'; import { beginPropertyChanges, @@ -18,25 +17,16 @@ function onEnd(current, next) { run.currentRunLoop = next; } -const onErrorTarget = { - get onerror() { - return dispatchError; - }, - set onerror(handler) { - return setOnerror(handler); - } -}; - const backburner = new Backburner(['sync', 'actions', 'destroy'], { - GUID_KEY: GUID_KEY, + GUID_KEY, sync: { before: beginPropertyChanges, after: endPropertyChanges }, defaultQueue: 'actions', - onBegin: onBegin, - onEnd: onEnd, - onErrorTarget: onErrorTarget, + onBegin, + onEnd, + onErrorTarget, onErrorMethod: 'onerror' }); diff --git a/packages/ember-metal/tests/error_handler_test.js b/packages/ember-metal/tests/error_handler_test.js new file mode 100644 index 00000000000..d8baa7ed1df --- /dev/null +++ b/packages/ember-metal/tests/error_handler_test.js @@ -0,0 +1,56 @@ +import Ember from 'ember'; +import { run } from 'ember-metal'; + +const ONERROR = Ember.onerror; +const ADAPTER = Ember.Test.adapter; + +QUnit.module('error_handler', { + afterEach() { + Ember.onerror = ONERROR; + Ember.Test.adapter = ADAPTER; + } +}); + +function runThatThrows(message) { + return run(() => { + throw new Error(message); + }); +} + +test('by default there is no onerror', function(assert) { + Ember.onerror = undefined; + assert.throws(runThatThrows, Error); + assert.equal(Ember.onerror, undefined); +}); + +test('when Ember.onerror is registered', function(assert) { + assert.expect(1); + Ember.error = function() { + assert.ok(true, 'onerror called'); + }; + assert.throws(runThatThrows, Error); +}); + +test('when Ember.Test.adapter is registered', function(assert) { + assert.expect(1); + + Ember.Test.adapter = function() { + assert.ok(true, 'adapter called'); + }; + assert.throws(runThatThrows, Error); +}); + +test('when both Ember.onerror Ember.Test.adapter is registered', function(assert) { + assert.expect(1); + + Ember.Test.adapter = function() { + assert.ok(true, 'adapter called'); + }; + + Ember.error = function() { + assert.ok(false, 'onerror was NEVER called'); + }; + + assert.throws(runThatThrows, Error); +}); +