fix(exception_handler): log errors via `console.error`

This is e.g. needed as we use this to test for errors
in our examples.
This commit is contained in:
Tobias Bosch 2015-04-30 11:25:50 -07:00
parent 87dcd5eb6f
commit ead21c91a4
10 changed files with 52 additions and 20 deletions

View File

@ -134,7 +134,7 @@ function _injectorBindings(appComponentType): List<Binding> {
function _createVmZone(givenReporter:Function): VmTurnZone {
var defaultErrorReporter = (exception, stackTrace) => {
var longStackTrace = ListWrapper.join(stackTrace, "\n\n-----async gap-----\n");
print(`${exception}\n\n${longStackTrace}`);
DOM.logError(`${exception}\n\n${longStackTrace}`);
throw exception;
};

View File

@ -1,6 +1,7 @@
import {Injectable} from 'angular2/di';
import {isPresent, print} from 'angular2/src/facade/lang';
import {ListWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
import {DOM} from 'angular2/src/dom/dom_adapter';
/**
* Provides a hook for centralized exception handling.
@ -36,6 +37,6 @@ export class ExceptionHandler {
call(error, stackTrace = null, reason = null) {
var longStackTrace = isListLikeIterable(stackTrace) ? ListWrapper.join(stackTrace, "\n\n") : stackTrace;
var reasonStr = isPresent(reason) ? `\n${reason}` : '';
print(`${error}${reasonStr}\nSTACKTRACE:\n${longStackTrace}`);
DOM.logError(`${error}${reasonStr}\nSTACKTRACE:\n${longStackTrace}`);
}
}

View File

@ -100,6 +100,10 @@ class BrowserDomAdapter extends GenericBrowserDomAdapter {
setRootDomAdapter(new BrowserDomAdapter());
}
logError(error) {
window.console.error(error);
}
@override
Map<String, String> get attrToPropMap => const <String, String>{
'innerHtml': 'innerHtml',

View File

@ -57,6 +57,10 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
setRootDomAdapter(new BrowserDomAdapter());
}
logError(error) {
window.console.error(error);
}
get attrToPropMap() {
return _attrToPropMap;
}

View File

@ -16,6 +16,10 @@ function _abstract() {
@ABSTRACT()
export class DomAdapter {
logError(error) {
throw _abstract();
}
/**
* Maps attribute names to their corresponding property names for cases
* where attribute name doesn't match property name.

View File

@ -3,12 +3,17 @@ library angular2.dom.htmlAdapter;
import 'dom_adapter.dart';
import 'package:html/parser.dart' as parser;
import 'package:html/dom.dart';
import 'dart:io';
class Html5LibDomAdapter implements DomAdapter {
static void makeCurrent() {
setRootDomAdapter(new Html5LibDomAdapter());
}
logError(error) {
stderr.writeln('${error}');
}
@override
final attrToPropMap = const {
'innerHtml': 'innerHtml',

View File

@ -28,6 +28,10 @@ export class Parse5DomAdapter extends DomAdapter {
setRootDomAdapter(new Parse5DomAdapter());
}
logError(error) {
console.error(error);
}
get attrToPropMap() {
return _attrToPropMap;
}

View File

@ -6,6 +6,9 @@ describe('sourcemaps', function () {
it('should map sources', function() {
browser.get(URL);
$('error-app .errorButton').click();
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
// so that the browser logs can be read out!
browser.executeScript('1+1');
@ -13,7 +16,7 @@ describe('sourcemaps', function () {
var errorLine = null;
var errorColumn = null;
logs.forEach(function(log) {
var match = /Test\.run\s+\(.+:(\d+):(\d+)/m.exec(log.message);
var match = /\.createError\s+\(.+:(\d+):(\d+)/m.exec(log.message);
if (match) {
errorLine = parseInt(match[1]);
errorColumn = parseInt(match[2]);

View File

@ -2,8 +2,15 @@
<html>
<title>Sourcemaps</title>
<body>
<error-app>
Loading...
</error-app>
<p>
Please look into the console and check whether the stack trace is mapped
via source maps!
</p>
$SCRIPTS$
</body>
</html>

View File

@ -1,24 +1,24 @@
import { BaseException, print, CONST } from 'angular2/src/facade/lang';
import { bootstrap } from 'angular2/angular2';
// TODO(radokirov): Once the application is transpiled by TS instead of Traceur,
// add those imports back into 'angular2/angular2';
import {Component} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
class TestAnnotation {
@CONST()
constructor() {}
}
// Use a class with an annotation,
// as this is where we expect the most source code changes
// through compilation.
@TestAnnotation()
class Test {
run() {
try {
throw new BaseException('Sourcemap test');
} catch (e) {
print(e);
}
@Component({
selector: 'error-app',
})
@View({
template: `
<button class="errorButton" (click)="createError()">create error</button>`,
directives: []
})
export class ErrorComponent {
createError() {
throw new BaseException('Sourcemap test');
}
}
export function main() {
new Test().run();
bootstrap(ErrorComponent);
}