refactor(core): move facades out of core
This is part of ongoing work to make core platform-independent.
BREAKING CHANGE
All private exports from 'angular2/src/core/facade/{lang,collection,exception_handler}' should be replaced with 'angular2/src/facade/{lang,collection,exception_handler}'.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {ListWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
|
||||
|
||||
class _ArrayLogger {
|
||||
res: any[] = [];
|
||||
log(s: any): void { this.res.push(s); }
|
||||
logError(s: any): void { this.res.push(s); }
|
||||
logGroup(s: any): void { this.res.push(s); }
|
||||
logGroupEnd(){};
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a hook for centralized exception handling.
|
||||
*
|
||||
* The default implementation of `ExceptionHandler` prints error messages to the `Console`. To
|
||||
* intercept error handling,
|
||||
* write a custom exception handler that replaces this default as appropriate for your app.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```javascript
|
||||
*
|
||||
* class MyExceptionHandler implements ExceptionHandler {
|
||||
* call(error, stackTrace = null, reason = null) {
|
||||
* // do something with the exception
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* bootstrap(MyApp, [provide(ExceptionHandler, {useClass: MyExceptionHandler})])
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export class ExceptionHandler {
|
||||
constructor(private _logger: any, private _rethrowException: boolean = true) {}
|
||||
|
||||
static exceptionToString(exception: any, stackTrace: any = null, reason: string = null): string {
|
||||
var l = new _ArrayLogger();
|
||||
var e = new ExceptionHandler(l, false);
|
||||
e.call(exception, stackTrace, reason);
|
||||
return l.res.join("\n");
|
||||
}
|
||||
|
||||
call(exception: any, stackTrace: any = null, reason: string = null): void {
|
||||
var originalException = this._findOriginalException(exception);
|
||||
var originalStack = this._findOriginalStack(exception);
|
||||
var context = this._findContext(exception);
|
||||
|
||||
this._logger.logGroup(`EXCEPTION: ${this._extractMessage(exception)}`);
|
||||
|
||||
if (isPresent(stackTrace) && isBlank(originalStack)) {
|
||||
this._logger.logError("STACKTRACE:");
|
||||
this._logger.logError(this._longStackTrace(stackTrace));
|
||||
}
|
||||
|
||||
if (isPresent(reason)) {
|
||||
this._logger.logError(`REASON: ${reason}`);
|
||||
}
|
||||
|
||||
if (isPresent(originalException)) {
|
||||
this._logger.logError(`ORIGINAL EXCEPTION: ${this._extractMessage(originalException)}`);
|
||||
}
|
||||
|
||||
if (isPresent(originalStack)) {
|
||||
this._logger.logError("ORIGINAL STACKTRACE:");
|
||||
this._logger.logError(this._longStackTrace(originalStack));
|
||||
}
|
||||
|
||||
if (isPresent(context)) {
|
||||
this._logger.logError("ERROR CONTEXT:");
|
||||
this._logger.logError(context);
|
||||
}
|
||||
|
||||
this._logger.logGroupEnd();
|
||||
|
||||
// We rethrow exceptions, so operations like 'bootstrap' will result in an error
|
||||
// when an exception happens. If we do not rethrow, bootstrap will always succeed.
|
||||
if (this._rethrowException) throw exception;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_extractMessage(exception: any): string {
|
||||
return exception instanceof WrappedException ? exception.wrapperMessage : exception.toString();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_longStackTrace(stackTrace: any): any {
|
||||
return isListLikeIterable(stackTrace) ? (<any[]>stackTrace).join("\n\n-----async gap-----\n") :
|
||||
stackTrace.toString();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_findContext(exception: any): any {
|
||||
try {
|
||||
if (!(exception instanceof WrappedException)) return null;
|
||||
return isPresent(exception.context) ? exception.context :
|
||||
this._findContext(exception.originalException);
|
||||
} catch (e) {
|
||||
// exception.context can throw an exception. if it happens, we ignore the context.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_findOriginalException(exception: any): any {
|
||||
if (!(exception instanceof WrappedException)) return null;
|
||||
|
||||
var e = exception.originalException;
|
||||
while (e instanceof WrappedException && isPresent(e.originalException)) {
|
||||
e = e.originalException;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_findOriginalStack(exception: any): any {
|
||||
if (!(exception instanceof WrappedException)) return null;
|
||||
|
||||
var e = exception;
|
||||
var stack = exception.originalStack;
|
||||
while (e instanceof WrappedException && isPresent(e.originalException)) {
|
||||
e = e.originalException;
|
||||
if (e instanceof WrappedException && isPresent(e.originalException)) {
|
||||
stack = e.originalStack;
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user