Skip to content

Commit

Permalink
feat(exception_handler): change ExceptionHandler to output context
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Jul 23, 2015
1 parent bd65b63 commit fdf226a
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 15 deletions.
44 changes: 29 additions & 15 deletions modules/angular2/src/core/exception_handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Injectable} from 'angular2/di';
import {isPresent, print} from 'angular2/src/facade/lang';
import {isPresent, print, BaseException} from 'angular2/src/facade/lang';
import {ListWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
import {DOM} from 'angular2/src/dom/dom_adapter';

Expand All @@ -13,30 +13,44 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
* # Example
*
* ```javascript
* @Component({
* selector: 'my-app',
* viewInjector: [
* bind(ExceptionHandler).toClass(MyExceptionHandler)
* ]
* })
* @View(...)
* class MyApp { ... }
*
*
* class MyExceptionHandler implements ExceptionHandler {
* call(error, stackTrace = null, reason = null) {
* // do something with the exception
* }
* }
*
* bootstrap(MyApp, [bind(ExceptionHandler).toClass(MyExceptionHandler)])
*
* ```
*/
@Injectable()
export class ExceptionHandler {
call(error: Object, stackTrace: string | List<string> = null, reason: string = null) {
var longStackTrace =
isListLikeIterable(stackTrace) ? ListWrapper.join(<any>stackTrace, "\n\n") : stackTrace;
var reasonStr = isPresent(reason) ? `\n${reason}` : '';
DOM.logError(`${error}${reasonStr}\nSTACKTRACE:\n${longStackTrace}`);
logError: Function = DOM.logError;

call(exception: Object, stackTrace: string | string[] = null, reason: string = null) {
var longStackTrace = isListLikeIterable(stackTrace) ?
(<any>stackTrace).join("\n\n-----async gap-----\n") :
stackTrace;

this.logError(`${exception}\n\n${longStackTrace}`);

if (isPresent(reason)) {
this.logError(`Reason: ${reason}`);
}

var context = this._findContext(exception);
if (isPresent(context)) {
this.logError("Error Context:");
this.logError(context);
}

throw exception;
}

_findContext(exception: any): any {
if (!(exception instanceof BaseException)) return null;
return isPresent(exception.context) ? exception.context :
this._findContext(exception.originalException);
}
}
90 changes: 90 additions & 0 deletions modules/angular2/test/core/exception_handler_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xdescribe,
xit,
IS_DARTIUM,
Log
} from 'angular2/test_lib';
import {BaseException} from 'angular2/src/facade/lang';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';

class _CustomException {
context = "some context";
}

export function main() {
describe('ExceptionHandler', () => {
var log, handler;

beforeEach(() => {
log = new Log();
handler = new ExceptionHandler();
handler.logError = (e) => log.add(e);
});

it("should output exception", () => {
try {
handler.call(new BaseException("message!"));
} catch (e) {
}
expect(log.result()).toContain("message!");
});

it("should output stackTrace", () => {
try {
handler.call(new BaseException("message!"), "stack!");
} catch (e) {
}
expect(log.result()).toContain("stack!");
});

it("should join a long stackTrace", () => {
try {
handler.call(new BaseException("message!"), ["stack1", "stack2"]);
} catch (e) {
}
expect(log.result()).toContain("stack1");
expect(log.result()).toContain("stack2");
});

it("should output reason when present", () => {
try {
handler.call(new BaseException("message!"), null, "reason!");
} catch (e) {
}
expect(log.result()).toContain("reason!");
});

it("should print context", () => {
try {
handler.call(new BaseException("message!", null, null, "context!"));
} catch (e) {
}
expect(log.result()).toContain("context!");
});

it("should print nested context", () => {
try {
var original = new BaseException("message!", null, null, "context!");
handler.call(new BaseException("message", original));
} catch (e) {
}
expect(log.result()).toContain("context!");
});

it("should not print context when the passed-in exception is not a BaseException", () => {
try {
handler.call(new _CustomException());
} catch (e) {
}
expect(log.result()).not.toContain("context");
});
});
}

0 comments on commit fdf226a

Please sign in to comment.