fix(change_detection): _throwError should not mask the original exception
This commit is contained in:
parent
5557a5716d
commit
cec4b36d9b
|
@ -287,11 +287,19 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _throwError(exception: any, stack: any): void {
|
private _throwError(exception: any, stack: any): void {
|
||||||
var c = this.dispatcher.getDebugContext(this._currentBinding().elementIndex, null);
|
var error;
|
||||||
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
|
try {
|
||||||
c.injector, this._currentBinding().debug) :
|
var c = this.dispatcher.getDebugContext(this._currentBinding().elementIndex, null);
|
||||||
null;
|
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
|
||||||
throw new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
|
c.injector, this._currentBinding().debug) :
|
||||||
|
null;
|
||||||
|
error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
|
||||||
|
} catch (e) {
|
||||||
|
// if an error happens during getting the debug context, we throw a ChangeDetectionError
|
||||||
|
// without the extra information.
|
||||||
|
error = new ChangeDetectionError(null, exception, stack, null);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
throwOnChangeError(oldValue: any, newValue: any): void {
|
throwOnChangeError(oldValue: any, newValue: any): void {
|
||||||
|
|
|
@ -254,7 +254,7 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher {
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: vsavkin log the exception once we have a good way to log errors and warnings
|
// TODO: vsavkin log the exception once we have a good way to log errors and warnings
|
||||||
// if an error happens during getting the debug context, we return an empty map.
|
// if an error happens during getting the debug context, we return null.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
fakeAsync
|
fakeAsync
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import {SpyChangeDispatcher} from '../spies';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CONST_EXPR,
|
CONST_EXPR,
|
||||||
isPresent,
|
isPresent,
|
||||||
|
@ -92,8 +94,8 @@ export function main() {
|
||||||
|
|
||||||
|
|
||||||
function _createChangeDetector(expression: string, context = _DEFAULT_CONTEXT,
|
function _createChangeDetector(expression: string, context = _DEFAULT_CONTEXT,
|
||||||
registry = null) {
|
registry = null, dispatcher = null) {
|
||||||
var dispatcher = new TestDispatcher();
|
if (isBlank(dispatcher)) dispatcher = new TestDispatcher();
|
||||||
var testDef = getDefinition(expression);
|
var testDef = getDefinition(expression);
|
||||||
var protoCd = _getProtoChangeDetector(testDef.cdDef);
|
var protoCd = _getProtoChangeDetector(testDef.cdDef);
|
||||||
var cd = protoCd.instantiate(dispatcher);
|
var cd = protoCd.instantiate(dispatcher);
|
||||||
|
@ -797,6 +799,22 @@ export function main() {
|
||||||
expect(e.location).toEqual('invalidFn(1) in location');
|
expect(e.location).toEqual('invalidFn(1) in location');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle unexpected errors in the event handler itself', () => {
|
||||||
|
var throwingDispatcher = new SpyChangeDispatcher();
|
||||||
|
throwingDispatcher.spy("getDebugContext")
|
||||||
|
.andCallFake((_, __) => { throw new BaseException('boom'); });
|
||||||
|
|
||||||
|
var val =
|
||||||
|
_createChangeDetector('invalidFn(1)', _DEFAULT_CONTEXT, null, throwingDispatcher);
|
||||||
|
try {
|
||||||
|
val.changeDetector.detectChanges();
|
||||||
|
throw new BaseException('fail');
|
||||||
|
} catch (e) {
|
||||||
|
expect(e).toBeAnInstanceOf(ChangeDetectionError);
|
||||||
|
expect(e.location).toEqual(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Locals', () => {
|
describe('Locals', () => {
|
||||||
|
@ -1398,5 +1416,5 @@ class TestDispatcher implements ChangeDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChangeDetectorAndDispatcher {
|
class _ChangeDetectorAndDispatcher {
|
||||||
constructor(public changeDetector: any, public dispatcher: TestDispatcher) {}
|
constructor(public changeDetector: any, public dispatcher: any) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,11 @@ class SpyProtoChangeDetector extends SpyObject implements ProtoChangeDetector {
|
||||||
noSuchMethod(m) => super.noSuchMethod(m);
|
noSuchMethod(m) => super.noSuchMethod(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@proxy
|
||||||
|
class SpyChangeDispatcher extends SpyObject implements ChangeDispatcher {
|
||||||
|
noSuchMethod(m) => super.noSuchMethod(m);
|
||||||
|
}
|
||||||
|
|
||||||
@proxy
|
@proxy
|
||||||
class SpyIterableDifferFactory extends SpyObject
|
class SpyIterableDifferFactory extends SpyObject
|
||||||
implements IterableDifferFactory {
|
implements IterableDifferFactory {
|
||||||
|
|
|
@ -40,6 +40,8 @@ export class SpyProtoChangeDetector extends SpyObject {
|
||||||
constructor() { super(DynamicChangeDetector); }
|
constructor() { super(DynamicChangeDetector); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SpyChangeDispatcher extends SpyObject {}
|
||||||
|
|
||||||
export class SpyIterableDifferFactory extends SpyObject {}
|
export class SpyIterableDifferFactory extends SpyObject {}
|
||||||
|
|
||||||
export class SpyRenderCompiler extends SpyObject {
|
export class SpyRenderCompiler extends SpyObject {
|
||||||
|
|
Loading…
Reference in New Issue