fix(Compiler): Catch exceptions in the logging of binding update
fixes #9994
This commit is contained in:
parent
b4ea0b1601
commit
27436270fd
@ -193,13 +193,13 @@ export enum BuiltinVar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ReadVarExpr extends Expression {
|
export class ReadVarExpr extends Expression {
|
||||||
public name: any /** TODO #9100 */;
|
public name: string;
|
||||||
public builtin: BuiltinVar;
|
public builtin: BuiltinVar;
|
||||||
|
|
||||||
constructor(name: string|BuiltinVar, type: Type = null) {
|
constructor(name: string|BuiltinVar, type: Type = null) {
|
||||||
super(type);
|
super(type);
|
||||||
if (isString(name)) {
|
if (isString(name)) {
|
||||||
this.name = <string>name;
|
this.name = name;
|
||||||
this.builtin = null;
|
this.builtin = null;
|
||||||
} else {
|
} else {
|
||||||
this.name = null;
|
this.name = null;
|
||||||
@ -270,7 +270,7 @@ export class InvokeMethodExpr extends Expression {
|
|||||||
type: Type = null) {
|
type: Type = null) {
|
||||||
super(type);
|
super(type);
|
||||||
if (isString(method)) {
|
if (isString(method)) {
|
||||||
this.name = <string>method;
|
this.name = method;
|
||||||
this.builtin = null;
|
this.builtin = null;
|
||||||
} else {
|
} else {
|
||||||
this.name = null;
|
this.name = null;
|
||||||
|
@ -11,19 +11,13 @@ import * as cdAst from '../expression_parser/ast';
|
|||||||
import {isBlank, isPresent} from '../facade/lang';
|
import {isBlank, isPresent} from '../facade/lang';
|
||||||
import {Identifiers} from '../identifiers';
|
import {Identifiers} from '../identifiers';
|
||||||
import * as o from '../output/output_ast';
|
import * as o from '../output/output_ast';
|
||||||
|
|
||||||
import {DetectChangesVars, ViewProperties} from './constants';
|
import {DetectChangesVars, ViewProperties} from './constants';
|
||||||
|
|
||||||
import {BoundTextAst, BoundElementPropertyAst, DirectiveAst, PropertyBindingType,} from '../template_ast';
|
import {BoundTextAst, BoundElementPropertyAst, DirectiveAst, PropertyBindingType,} from '../template_ast';
|
||||||
|
|
||||||
import {CompileView} from './compile_view';
|
import {CompileView} from './compile_view';
|
||||||
import {CompileElement, CompileNode} from './compile_element';
|
import {CompileElement, CompileNode} from './compile_element';
|
||||||
import {CompileMethod} from './compile_method';
|
import {CompileMethod} from './compile_method';
|
||||||
|
|
||||||
import {camelCaseToDashCase} from '../util';
|
import {camelCaseToDashCase} from '../util';
|
||||||
|
|
||||||
import {convertCdExpressionToIr} from './expression_converter';
|
import {convertCdExpressionToIr} from './expression_converter';
|
||||||
|
|
||||||
import {CompileBinding} from './compile_binding';
|
import {CompileBinding} from './compile_binding';
|
||||||
import {BaseException, SecurityContext} from '@angular/core';
|
import {BaseException, SecurityContext} from '@angular/core';
|
||||||
|
|
||||||
@ -287,12 +281,24 @@ export function bindDirectiveInputs(
|
|||||||
|
|
||||||
function logBindingUpdateStmt(
|
function logBindingUpdateStmt(
|
||||||
renderNode: o.Expression, propName: string, value: o.Expression): o.Statement {
|
renderNode: o.Expression, propName: string, value: o.Expression): o.Statement {
|
||||||
return o.THIS_EXPR.prop('renderer')
|
const tryStmt =
|
||||||
.callMethod(
|
o.THIS_EXPR.prop('renderer')
|
||||||
'setBindingDebugInfo',
|
.callMethod(
|
||||||
[
|
'setBindingDebugInfo',
|
||||||
renderNode, o.literal(`ng-reflect-${camelCaseToDashCase(propName)}`),
|
[
|
||||||
value.isBlank().conditional(o.NULL_EXPR, value.callMethod('toString', []))
|
renderNode, o.literal(`ng-reflect-${camelCaseToDashCase(propName)}`),
|
||||||
])
|
value.isBlank().conditional(o.NULL_EXPR, value.callMethod('toString', []))
|
||||||
.toStmt();
|
])
|
||||||
|
.toStmt();
|
||||||
|
|
||||||
|
const catchStmt = o.THIS_EXPR.prop('renderer')
|
||||||
|
.callMethod(
|
||||||
|
'setBindingDebugInfo',
|
||||||
|
[
|
||||||
|
renderNode, o.literal(`ng-reflect-${camelCaseToDashCase(propName)}`),
|
||||||
|
o.literal('[ERROR] Exception while trying to serialize the value')
|
||||||
|
])
|
||||||
|
.toStmt();
|
||||||
|
|
||||||
|
return new o.TryCatchStmt([tryStmt], [catchStmt]);
|
||||||
}
|
}
|
||||||
|
@ -69,16 +69,13 @@ export abstract class Renderer {
|
|||||||
abstract setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string):
|
abstract setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string):
|
||||||
void;
|
void;
|
||||||
|
|
||||||
abstract setElementClass(renderElement: any, className: string, isAdd: boolean): any
|
abstract setElementClass(renderElement: any, className: string, isAdd: boolean): void;
|
||||||
/** TODO #9100 */;
|
|
||||||
|
|
||||||
abstract setElementStyle(renderElement: any, styleName: string, styleValue: string): any
|
abstract setElementStyle(renderElement: any, styleName: string, styleValue: string): void;
|
||||||
/** TODO #9100 */;
|
|
||||||
|
|
||||||
abstract invokeElementMethod(renderElement: any, methodName: string, args?: any[]): any
|
abstract invokeElementMethod(renderElement: any, methodName: string, args?: any[]): void;
|
||||||
/** TODO #9100 */;
|
|
||||||
|
|
||||||
abstract setText(renderNode: any, text: string): any /** TODO #9100 */;
|
abstract setText(renderNode: any, text: string): void;
|
||||||
|
|
||||||
abstract animate(
|
abstract animate(
|
||||||
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
|
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
|
||||||
|
@ -1846,6 +1846,21 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should indicate when toString() throws',
|
||||||
|
inject(
|
||||||
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
var tpl = '<div my-dir [elprop]="toStringThrow"></div>';
|
||||||
|
tcb.overrideView(MyComp, new ViewMetadata({template: tpl, directives: [MyDir]}))
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getDOM().getInnerHTML(fixture.debugElement.nativeElement))
|
||||||
|
.toContain('[ERROR]');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('property decorators', () => {
|
describe('property decorators', () => {
|
||||||
@ -2227,6 +2242,8 @@ class MyComp {
|
|||||||
ctxProp: string;
|
ctxProp: string;
|
||||||
ctxNumProp: number;
|
ctxNumProp: number;
|
||||||
ctxBoolProp: boolean;
|
ctxBoolProp: boolean;
|
||||||
|
toStringThrow = {toString: function() { throw 'boom'; }};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.ctxProp = 'initial value';
|
this.ctxProp = 'initial value';
|
||||||
this.ctxNumProp = 0;
|
this.ctxNumProp = 0;
|
||||||
|
8
tools/public_api_guard/core/index.d.ts
vendored
8
tools/public_api_guard/core/index.d.ts
vendored
@ -1218,17 +1218,17 @@ export declare abstract class Renderer {
|
|||||||
abstract createViewRoot(hostElement: any): any;
|
abstract createViewRoot(hostElement: any): any;
|
||||||
abstract destroyView(hostElement: any, viewAllNodes: any[]): void;
|
abstract destroyView(hostElement: any, viewAllNodes: any[]): void;
|
||||||
abstract detachView(viewRootNodes: any[]): void;
|
abstract detachView(viewRootNodes: any[]): void;
|
||||||
abstract invokeElementMethod(renderElement: any, methodName: string, args?: any[]): any;
|
abstract invokeElementMethod(renderElement: any, methodName: string, args?: any[]): void;
|
||||||
abstract listen(renderElement: any, name: string, callback: Function): Function;
|
abstract listen(renderElement: any, name: string, callback: Function): Function;
|
||||||
abstract listenGlobal(target: string, name: string, callback: Function): Function;
|
abstract listenGlobal(target: string, name: string, callback: Function): Function;
|
||||||
abstract projectNodes(parentElement: any, nodes: any[]): void;
|
abstract projectNodes(parentElement: any, nodes: any[]): void;
|
||||||
abstract selectRootElement(selectorOrNode: string | any, debugInfo?: RenderDebugInfo): any;
|
abstract selectRootElement(selectorOrNode: string | any, debugInfo?: RenderDebugInfo): any;
|
||||||
abstract setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string): void;
|
abstract setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string): void;
|
||||||
abstract setElementAttribute(renderElement: any, attributeName: string, attributeValue: string): void;
|
abstract setElementAttribute(renderElement: any, attributeName: string, attributeValue: string): void;
|
||||||
abstract setElementClass(renderElement: any, className: string, isAdd: boolean): any;
|
abstract setElementClass(renderElement: any, className: string, isAdd: boolean): void;
|
||||||
abstract setElementProperty(renderElement: any, propertyName: string, propertyValue: any): void;
|
abstract setElementProperty(renderElement: any, propertyName: string, propertyValue: any): void;
|
||||||
abstract setElementStyle(renderElement: any, styleName: string, styleValue: string): any;
|
abstract setElementStyle(renderElement: any, styleName: string, styleValue: string): void;
|
||||||
abstract setText(renderNode: any, text: string): any;
|
abstract setText(renderNode: any, text: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user