X Tutup
Skip to content

Commit cec4b36

Browse files
committed
fix(change_detection): _throwError should not mask the original exception
1 parent 5557a57 commit cec4b36

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

modules/angular2/src/core/change_detection/abstract_change_detector.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,19 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
287287
}
288288

289289
private _throwError(exception: any, stack: any): void {
290-
var c = this.dispatcher.getDebugContext(this._currentBinding().elementIndex, null);
291-
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
292-
c.injector, this._currentBinding().debug) :
293-
null;
294-
throw new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
290+
var error;
291+
try {
292+
var c = this.dispatcher.getDebugContext(this._currentBinding().elementIndex, null);
293+
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
294+
c.injector, this._currentBinding().debug) :
295+
null;
296+
error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
297+
} catch (e) {
298+
// if an error happens during getting the debug context, we throw a ChangeDetectionError
299+
// without the extra information.
300+
error = new ChangeDetectionError(null, exception, stack, null);
301+
}
302+
throw error;
295303
}
296304

297305
throwOnChangeError(oldValue: any, newValue: any): void {

modules/angular2/src/core/compiler/view.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher {
254254

255255
} catch (e) {
256256
// TODO: vsavkin log the exception once we have a good way to log errors and warnings
257-
// if an error happens during getting the debug context, we return an empty map.
257+
// if an error happens during getting the debug context, we return null.
258258
return null;
259259
}
260260
}

modules/angular2/test/core/change_detection/change_detector_spec.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
fakeAsync
1212
} from 'angular2/test_lib';
1313

14+
import {SpyChangeDispatcher} from '../spies';
15+
1416
import {
1517
CONST_EXPR,
1618
isPresent,
@@ -92,8 +94,8 @@ export function main() {
9294

9395

9496
function _createChangeDetector(expression: string, context = _DEFAULT_CONTEXT,
95-
registry = null) {
96-
var dispatcher = new TestDispatcher();
97+
registry = null, dispatcher = null) {
98+
if (isBlank(dispatcher)) dispatcher = new TestDispatcher();
9799
var testDef = getDefinition(expression);
98100
var protoCd = _getProtoChangeDetector(testDef.cdDef);
99101
var cd = protoCd.instantiate(dispatcher);
@@ -797,6 +799,22 @@ export function main() {
797799
expect(e.location).toEqual('invalidFn(1) in location');
798800
}
799801
});
802+
803+
it('should handle unexpected errors in the event handler itself', () => {
804+
var throwingDispatcher = new SpyChangeDispatcher();
805+
throwingDispatcher.spy("getDebugContext")
806+
.andCallFake((_, __) => { throw new BaseException('boom'); });
807+
808+
var val =
809+
_createChangeDetector('invalidFn(1)', _DEFAULT_CONTEXT, null, throwingDispatcher);
810+
try {
811+
val.changeDetector.detectChanges();
812+
throw new BaseException('fail');
813+
} catch (e) {
814+
expect(e).toBeAnInstanceOf(ChangeDetectionError);
815+
expect(e.location).toEqual(null);
816+
}
817+
});
800818
});
801819

802820
describe('Locals', () => {
@@ -1398,5 +1416,5 @@ class TestDispatcher implements ChangeDispatcher {
13981416
}
13991417

14001418
class _ChangeDetectorAndDispatcher {
1401-
constructor(public changeDetector: any, public dispatcher: TestDispatcher) {}
1419+
constructor(public changeDetector: any, public dispatcher: any) {}
14021420
}

modules/angular2/test/core/spies.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class SpyProtoChangeDetector extends SpyObject implements ProtoChangeDetector {
3535
noSuchMethod(m) => super.noSuchMethod(m);
3636
}
3737

38+
@proxy
39+
class SpyChangeDispatcher extends SpyObject implements ChangeDispatcher {
40+
noSuchMethod(m) => super.noSuchMethod(m);
41+
}
42+
3843
@proxy
3944
class SpyIterableDifferFactory extends SpyObject
4045
implements IterableDifferFactory {

modules/angular2/test/core/spies.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export class SpyProtoChangeDetector extends SpyObject {
4040
constructor() { super(DynamicChangeDetector); }
4141
}
4242

43+
export class SpyChangeDispatcher extends SpyObject {}
44+
4345
export class SpyIterableDifferFactory extends SpyObject {}
4446

4547
export class SpyRenderCompiler extends SpyObject {

0 commit comments

Comments
 (0)
X Tutup