Skip to content

Commit

Permalink
fix(navcontroller): exceptions inside lifecycle events are printed pr…
Browse files Browse the repository at this point in the history
…operly

fixes #10974
  • Loading branch information
manucorporat committed Apr 19, 2017
1 parent a5a85de commit 95c06a5
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 40 deletions.
5 changes: 3 additions & 2 deletions src/components/nav/nav.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AfterViewInit, Component, ComponentFactoryResolver, ElementRef, forwardRef, Input, Optional, NgZone, Renderer, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
import { AfterViewInit, Component, ComponentFactoryResolver, ElementRef, ErrorHandler, forwardRef, Input, Optional, NgZone, Renderer, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';

import { App } from '../app/app';
import { Config } from '../../config/config';
Expand Down Expand Up @@ -74,8 +74,9 @@ export class Nav extends NavControllerBase implements AfterViewInit, RootNode {
transCtrl: TransitionController,
@Optional() linker: DeepLinker,
domCtrl: DomController,
errHandler: ErrorHandler
) {
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl);
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);

if (viewCtrl) {
// an ion-nav can also act as an ion-page within a parent ion-nav
Expand Down
5 changes: 3 additions & 2 deletions src/components/nav/overlay-portal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentFactoryResolver, Directive, ElementRef, forwardRef, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef } from '@angular/core';
import { ComponentFactoryResolver, Directive, ElementRef, ErrorHandler, forwardRef, Inject, Input, NgZone, Optional, Renderer, ViewContainerRef } from '@angular/core';

import { App } from '../app/app';
import { Config } from '../../config/config';
Expand Down Expand Up @@ -31,8 +31,9 @@ export class OverlayPortal extends NavControllerBase {
@Optional() linker: DeepLinker,
viewPort: ViewContainerRef,
domCtrl: DomController,
errHandler: ErrorHandler
) {
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl);
super(null, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, domCtrl, errHandler);
this._isPortal = true;
this._init = true;
this.setViewport(viewPort);
Expand Down
3 changes: 2 additions & 1 deletion src/components/nav/test/nav.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ function getNav() {
gestureCtrl,
trnsCtrl,
linker,
dom
dom,
null
);
return nav;
}
5 changes: 3 additions & 2 deletions src/components/tabs/tab.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, ElementRef, EventEmitter, Input, NgZone, Optional, Output, Renderer, ViewChild, ViewEncapsulation, ViewContainerRef } from '@angular/core';
import { ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, ElementRef, ErrorHandler, EventEmitter, Input, NgZone, Optional, Output, Renderer, ViewChild, ViewEncapsulation, ViewContainerRef } from '@angular/core';

import { App } from '../app/app';
import { Config } from '../../config/config';
Expand Down Expand Up @@ -264,9 +264,10 @@ export class Tab extends NavControllerBase {
transCtrl: TransitionController,
@Optional() private linker: DeepLinker,
private _dom: DomController,
errHandler: ErrorHandler
) {
// A Tab is a NavController for its child pages
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom);
super(parent, app, config, plt, keyboard, elementRef, zone, renderer, cfr, gestureCtrl, transCtrl, linker, _dom, errHandler);

this.id = parent.add(this);
this._tabsHideOnSubPages = config.getBoolean('tabsHideOnSubPages');
Expand Down
73 changes: 51 additions & 22 deletions src/navigation/nav-controller-base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentRef, Input, ComponentFactoryResolver, ElementRef, EventEmitter, NgZone, ReflectiveInjector, Renderer, ViewContainerRef } from '@angular/core';
import { ComponentRef, Input, ComponentFactoryResolver, ElementRef, ErrorHandler, EventEmitter, NgZone, ReflectiveInjector, Renderer, ViewContainerRef } from '@angular/core';

import { AnimationOptions } from '../animations/animation';
import { App } from '../components/app/app';
Expand Down Expand Up @@ -71,7 +71,8 @@ export class NavControllerBase extends Ion implements NavController {
public _gestureCtrl: GestureController,
public _trnsCtrl: TransitionController,
public _linker: DeepLinker,
private _domCtrl: DomController
private _domCtrl: DomController,
private _errHandler: ErrorHandler
) {
super(config, elementRef, renderer);

Expand Down Expand Up @@ -350,7 +351,7 @@ export class NavControllerBase extends Ion implements NavController {
if (nav && nav !== this) {
throw 'inserted view was already inserted';
}
if (viewControllers[i]._state === STATE_DESTROYED) {
if (view._state === STATE_DESTROYED) {
throw 'inserted view was already destroyed';
}
}
Expand Down Expand Up @@ -857,61 +858,89 @@ export class NavControllerBase extends Ion implements NavController {
_willLoad(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');

view._willLoad();
try {
view._willLoad();
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_didLoad(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._didLoad();
this.viewDidLoad.emit(view);
this._app.viewDidLoad.emit(view);
try {
view._didLoad();
this.viewDidLoad.emit(view);
this._app.viewDidLoad.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_willEnter(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._willEnter();
this.viewWillEnter.emit(view);
this._app.viewWillEnter.emit(view);
try {
view._willEnter();
this.viewWillEnter.emit(view);
this._app.viewWillEnter.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_didEnter(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._didEnter();
this.viewDidEnter.emit(view);
this._app.viewDidEnter.emit(view);
try {
view._didEnter();
this.viewDidEnter.emit(view);
this._app.viewDidEnter.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_willLeave(view: ViewController, willUnload: boolean) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._willLeave(willUnload);
this.viewWillLeave.emit(view);
this._app.viewWillLeave.emit(view);
try {
view._willLeave(willUnload);
this.viewWillLeave.emit(view);
this._app.viewWillLeave.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_didLeave(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._didLeave();
this.viewDidLeave.emit(view);
this._app.viewDidLeave.emit(view);
try {
view._didLeave();
this.viewDidLeave.emit(view);
this._app.viewDidLeave.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

_willUnload(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');

view._willUnload();
this.viewWillUnload.emit(view);
this._app.viewWillUnload.emit(view);
try {
view._willUnload();
this.viewWillUnload.emit(view);
this._app.viewWillUnload.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}

hasChildren(): boolean {
Expand Down
18 changes: 10 additions & 8 deletions src/navigation/view-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ export class ViewController {
/** @hidden */
@Output() private _emitter: EventEmitter<any> = new EventEmitter();

constructor(public component?: any, data?: any, rootCssClass: string = DEFAULT_CSS_CLASS) {
constructor(
public component?: any,
data?: any,
rootCssClass: string = DEFAULT_CSS_CLASS
) {
// passed in data could be NavParams, but all we care about is its data object
this.data = (data instanceof NavParams ? data.data : (isPresent(data) ? data : {}));

Expand Down Expand Up @@ -541,7 +545,7 @@ export class ViewController {
/**
* @hidden
*/
_lifecycleTest(lifecycle: string): Promise<any> {
_lifecycleTest(lifecycle: string): Promise<boolean> {
const instance = this.instance;
const methodName = 'ionViewCan' + lifecycle;
if (instance && instance[methodName]) {
Expand All @@ -561,16 +565,14 @@ export class ViewController {
return Promise.resolve(true);
}

/**
* @hidden
*/
_lifecycle(lifecycle: string) {
const instance = this.instance;
const methodName = 'ionView' + lifecycle;
if (instance && instance[methodName]) {
try {
instance[methodName]();

} catch (e) {
console.error(`${this.name} ${methodName} error: ${e.message}`);
}
instance[methodName]();
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/util/mock-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ export function mockNavController(): NavControllerBase {
gestureCtrl,
trnsCtrl,
linker,
dom
dom,
null
);

nav._viewInit = function(enteringView: ViewController) {
Expand Down Expand Up @@ -468,7 +469,8 @@ export function mockOverlayPortal(app: App, config: Config, plt: MockPlatform):
null,
deepLinker,
null,
dom
dom,
null
);
}

Expand Down Expand Up @@ -500,7 +502,8 @@ export function mockTab(parentTabs: Tabs): Tab {
gestureCtrl,
null,
linker,
dom
dom,
null
);

tab.load = (opts: any, cb: Function) => {
Expand Down

0 comments on commit 95c06a5

Please sign in to comment.