Better tracing (logging) of run-time errors.

This commit is contained in:
Nedyalko Nikolov
2016-02-26 14:16:52 +02:00
parent bd2f2c751a
commit ba2a84de6b
6 changed files with 63 additions and 20 deletions

View File

@@ -47,7 +47,6 @@ export class UITest<T extends View> implements trace.TraceWriter {
}; };
trace.addWriter(this); trace.addWriter(this);
trace.enable();
navHelper.navigate(pageFactory); navHelper.navigate(pageFactory);
} }

View File

@@ -14,6 +14,7 @@ import labelModule = require("ui/label");
import textFieldModule = require("ui/text-field"); import textFieldModule = require("ui/text-field");
import fs = require("file-system"); import fs = require("file-system");
import appModule = require("application"); import appModule = require("application");
import trace = require("trace");
// <snippet module="ui/core/bindable" title="bindable"> // <snippet module="ui/core/bindable" title="bindable">
// For information and examples how to use bindings please refer to special [**Data binding**](../../../../bindings.md) topic. // For information and examples how to use bindings please refer to special [**Data binding**](../../../../bindings.md) topic.
@@ -693,6 +694,29 @@ export function test_NestedPropertiesBinding() {
TKUnit.assertEqual(target1.get("targetProperty"), newExpectedValue); TKUnit.assertEqual(target1.get("targetProperty"), newExpectedValue);
} }
export function test_WrongNestedPropertiesBinding() {
var expectedValue = "Default Text";
var viewModel = new observable.Observable();
viewModel.set("activity", new Activity(expectedValue, "Default First Name", "Default Last Name"));
let errorMessage;
let traceWriter = {
write: function (message, category, type?) {
errorMessage = message;
}
}
trace.addWriter(traceWriter);
var target1 = new bindable.Bindable();
target1.bind({
sourceProperty: "activity.",
targetProperty: "targetProperty",
twoWay: true
}, viewModel);
TKUnit.assertNotEqual(errorMessage, undefined);
trace.removeWriter(traceWriter);
}
export function test_NestedPropertiesBindingTwoTargets() { export function test_NestedPropertiesBindingTwoTargets() {
var expectedText = "Default Text"; var expectedText = "Default Text";
var expectedFirstName = "Default First Name"; var expectedFirstName = "Default First Name";

View File

@@ -48,6 +48,14 @@ export function addCategories(categories: string) {
} }
export function write(message: any, category: string, type?: number) { export function write(message: any, category: string, type?: number) {
// print error no matter what
var i;
if (type === messageType.error) {
for (i = 0; i < _writers.length; i++) {
_writers[i].write(message, category, type);
}
}
if (!_enabled) { if (!_enabled) {
return; return;
} }
@@ -56,7 +64,7 @@ export function write(message: any, category: string, type?: number) {
return; return;
} }
var i;
for (i = 0; i < _writers.length; i++) { for (i = 0; i < _writers.length; i++) {
_writers[i].write(message, category, type); _writers[i].write(message, category, type);
} }
@@ -113,6 +121,7 @@ export module categories {
export var Navigation = "Navigation"; export var Navigation = "Navigation";
export var Test = "Test"; export var Test = "Test";
export var Binding = "Binding"; export var Binding = "Binding";
export var BindingError = "BindingError";
export var Error = "Error"; export var Error = "Error";
export var Animation = "Animation"; export var Animation = "Animation";
export var Transition = "Transition"; export var Transition = "Transition";

View File

@@ -252,22 +252,25 @@ export class Binding {
var currentObjectChanged = false; var currentObjectChanged = false;
for (i = 0; i < propsArrayLength; i++) { for (i = 0; i < propsArrayLength; i++) {
objProp = propsArray[i]; objProp = propsArray[i];
if (propsArray[i] === bc.bindingValueKey) { if (objProp === bc.bindingValueKey) {
currentObjectChanged = true; currentObjectChanged = true;
} }
if (propsArray[i] === bc.parentValueKey || propsArray[i].indexOf(bc.parentsValueKey) === 0) { if (objProp === bc.parentValueKey || objProp.indexOf(bc.parentsValueKey) === 0) {
var parentView = this.getParentView(this.target.get(), propsArray[i]).view; var parentView = this.getParentView(this.target.get(), objProp).view;
if (parentView) { if (parentView) {
currentObject = parentView.bindingContext; currentObject = parentView.bindingContext;
} } else {
else {
var targetInstance = this.target.get(); var targetInstance = this.target.get();
targetInstance.off(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); targetInstance.off(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this);
targetInstance.on(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this); targetInstance.on(viewModule.View.loadedEvent, this.loadedHandlerVisualTreeBinding, this);
} }
currentObjectChanged = true; currentObjectChanged = true;
} }
result.push({ instance: currentObject, property: objProp }); if (currentObject) {
result.push({ instance: currentObject, property: objProp });
} else {
break;
}
// do not need to dive into last object property getter on binding stage will handle it // do not need to dive into last object property getter on binding stage will handle it
if (!currentObjectChanged && (i < propsArrayLength - 1)) { if (!currentObjectChanged && (i < propsArrayLength - 1)) {
currentObject = currentObject ? currentObject[propsArray[i]] : null; currentObject = currentObject ? currentObject[propsArray[i]] : null;
@@ -285,7 +288,7 @@ export class Binding {
for (i = 0; i < objectsAndPropertiesLength; i++) { for (i = 0; i < objectsAndPropertiesLength; i++) {
var prop = objectsAndProperties[i].property; var prop = objectsAndProperties[i].property;
var currentObject = objectsAndProperties[i].instance; var currentObject = objectsAndProperties[i].instance;
if (currentObject && !this.propertyChangeListeners[prop] && currentObject instanceof observable.Observable) { if (!this.propertyChangeListeners[prop] && currentObject instanceof observable.Observable) {
weakEvents.addWeakEventListener( weakEvents.addWeakEventListener(
currentObject, currentObject,
observable.Observable.propertyChangeEvent, observable.Observable.propertyChangeEvent,
@@ -504,13 +507,13 @@ export class Binding {
var sourceOptionsInstance = this.sourceOptions.instance.get(); var sourceOptionsInstance = this.sourceOptions.instance.get();
if (this.sourceOptions.property === bc.bindingValueKey) { if (this.sourceOptions.property === bc.bindingValueKey) {
value = sourceOptionsInstance; value = sourceOptionsInstance;
} } else if ((sourceOptionsInstance instanceof observable.Observable) && (this.sourceOptions.property && this.sourceOptions.property !== "")) {
else if (sourceOptionsInstance instanceof observable.Observable) {
value = sourceOptionsInstance.get(this.sourceOptions.property); value = sourceOptionsInstance.get(this.sourceOptions.property);
} } else if (sourceOptionsInstance && this.sourceOptions.property && this.sourceOptions.property !== "" &&
else if (sourceOptionsInstance && this.sourceOptions.property &&
this.sourceOptions.property in sourceOptionsInstance) { this.sourceOptions.property in sourceOptionsInstance) {
value = sourceOptionsInstance[this.sourceOptions.property]; value = sourceOptionsInstance[this.sourceOptions.property];
} else {
trace.write("Property: '" + this.sourceOptions.property + "' is invalid or does not exist. SourceProperty: '" + this.options.sourceProperty + "'", trace.categories.Binding, trace.messageType.error);
} }
} }
return value; return value;
@@ -564,8 +567,7 @@ export class Binding {
result = result.parent; result = result.parent;
indexAsInt--; indexAsInt--;
} }
} } else if (types.isString(index)) {
else if (types.isString(index)) {
while (result && result.typeName !== index) { while (result && result.typeName !== index) {
result = result.parent; result = result.parent;
} }
@@ -580,11 +582,9 @@ export class Binding {
if (objectsAndProperties.length > 0) { if (objectsAndProperties.length > 0) {
var resolvedObj = objectsAndProperties[objectsAndProperties.length - 1].instance; var resolvedObj = objectsAndProperties[objectsAndProperties.length - 1].instance;
var prop = objectsAndProperties[objectsAndProperties.length - 1].property; var prop = objectsAndProperties[objectsAndProperties.length - 1].property;
if (resolvedObj) {
return { return {
instance: new WeakRef(resolvedObj), instance: new WeakRef(resolvedObj),
property: prop property: prop
}
} }
} }
return null; return null;

View File

@@ -266,8 +266,9 @@ export function openUrl(location: string): boolean {
context.startActivity(intent); context.startActivity(intent);
} catch (e) { } catch (e) {
ensureTrace();
// We Don't do anything with an error. We just output it // We Don't do anything with an error. We just output it
console.error("Error in OpenURL", e); trace.write("Error in OpenURL", trace.categories.Error, trace.messageType.error);
return false; return false;
} }
return true; return true;

View File

@@ -4,9 +4,17 @@ import common = require("./utils-common");
import {Color} from "color"; import {Color} from "color";
import enums = require("ui/enums"); import enums = require("ui/enums");
import * as fsModule from "file-system"; import * as fsModule from "file-system";
import * as traceModule from "trace";
global.moduleMerge(common, exports); global.moduleMerge(common, exports);
var trace: typeof traceModule;
function ensureTrace() {
if (!trace) {
trace = require("trace");
}
}
function isOrientationLandscape(orientation: number) { function isOrientationLandscape(orientation: number) {
return orientation === UIDeviceOrientation.UIDeviceOrientationLandscapeLeft || orientation === UIDeviceOrientation.UIDeviceOrientationLandscapeRight; return orientation === UIDeviceOrientation.UIDeviceOrientationLandscapeLeft || orientation === UIDeviceOrientation.UIDeviceOrientationLandscapeRight;
} }
@@ -234,7 +242,8 @@ export module ios {
return controller.presentPreviewAnimated(true); return controller.presentPreviewAnimated(true);
} }
catch (e) { catch (e) {
console.error("Error in openFile", e); ensureTrace();
trace.write("Error in openFile", trace.categories.Error, trace.messageType.error);
} }
return false; return false;
} }
@@ -252,8 +261,9 @@ export function openUrl(location: string): boolean {
} }
} }
catch (e) { catch (e) {
ensureTrace();
// We Don't do anything with an error. We just output it // We Don't do anything with an error. We just output it
console.error("Error in OpenURL", e); trace.write("Error in OpenURL", trace.categories.Error, trace.messageType.error);
} }
return false; return false;
} }