diff --git a/common/changes/@uifabric/utilities/fix-error-handling_2018-02-13-02-38.json b/common/changes/@uifabric/utilities/fix-error-handling_2018-02-13-02-38.json new file mode 100644 index 00000000000000..ecd2c77dc8674e --- /dev/null +++ b/common/changes/@uifabric/utilities/fix-error-handling_2018-02-13-02-38.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/utilities", + "comment": "BaseComponent.onError default implementation removed, exceptions now simply bubble out which lets partners use React 16 error handling.", + "type": "minor" + } + ], + "packageName": "@uifabric/utilities", + "email": "dzearing@microsoft.com" +} \ No newline at end of file diff --git a/packages/utilities/src/BaseComponent.test.tsx b/packages/utilities/src/BaseComponent.test.tsx index bed1d511f4d9f2..75562ec33f2260 100644 --- a/packages/utilities/src/BaseComponent.test.tsx +++ b/packages/utilities/src/BaseComponent.test.tsx @@ -5,68 +5,7 @@ import * as React from 'react'; import * as ReactTestUtils from 'react-dom/test-utils'; import { BaseComponent } from './BaseComponent'; -let _originalOnError = BaseComponent.onError; - -class TestComponent extends BaseComponent<{}, {}> { - - public componentWillMount(): void { - this._createNullRef(); - } - - public componentDidMount(): void { - this._createNullRef(); - } - - public shouldComponentUpdate(nextProps?: {}, nextState?: {}): boolean { - this._createNullRef(); - - return true; - } - - public componentWillUpdate(): void { - this._createNullRef(); - } - - public componentWillReceiveProps(): void { - this._createNullRef(); - } - - public render(): JSX.Element | null { - this._createNullRef(); - return null; - } - - public componentDidUpdate(): void { - this._createNullRef(); - } - - public componentWillUnmount(): void { - this._createNullRef(); - } - - private _createNullRef(): void { - // tslint:disable-next-line:no-any - let foo: any = null; - - // Calling a null - foo(); - } -} - describe('BaseComponent', () => { - afterEach(() => { - BaseComponent.onError = _originalOnError; - }); - - _buildTestFor('componentWillMount'); - _buildTestFor('componentDidMount'); - _buildTestFor('shouldComponentUpdate'); - _buildTestFor('componentWillUpdate'); - _buildTestFor('componentWillReceiveProps'); - _buildTestFor('render'); - _buildTestFor('componentDidUpdate'); - _buildTestFor('componentWillUnmount'); - it('can resolve refs', () => { class Foo extends BaseComponent<{}, {}> { public root: HTMLElement; @@ -84,18 +23,3 @@ describe('BaseComponent', () => { expect(component.root).toBeDefined(); }); }); - -function _buildTestFor(methodName: string): void { - it(`calls the error logger on ${methodName} exception`, () => { - let lastErrorMessage; - - BaseComponent.onError = (errorMessage: string | undefined) => lastErrorMessage = errorMessage; - - let c = new TestComponent({}); - - // tslint:disable-next-line:no-any - (c as any)[methodName](); - - expect(lastErrorMessage).toBeDefined(); - }); -} \ No newline at end of file diff --git a/packages/utilities/src/BaseComponent.ts b/packages/utilities/src/BaseComponent.ts index 915e2840fd5498..0cfa0445e3cd01 100644 --- a/packages/utilities/src/BaseComponent.ts +++ b/packages/utilities/src/BaseComponent.ts @@ -21,8 +21,7 @@ export interface IBaseProps { */ export class BaseComponent

extends React.Component { /** - * External consumers should override BaseComponent.onError to hook into error messages that occur from - * exceptions thrown from within components. + * @deprecated Use React's error boundaries instead. */ // tslint:disable-next-line:no-any public static onError: ((errorMessage?: string, ex?: any) => void); @@ -241,19 +240,11 @@ function _makeSafe(obj: BaseComponent<{}, {}>, prototype: Object, methodName: st (obj as any)[methodName] = function (): any { let retVal; - try { - if (prototypeMethod) { - retVal = prototypeMethod.apply(this, arguments); - } - if (classMethod !== prototypeMethod) { - retVal = classMethod.apply(this, arguments); - } - } catch (e) { - const errorMessage = `Exception in ${obj.className}.${methodName}(): ${typeof e === 'string' ? e : e.stack}`; - - if (BaseComponent.onError) { - BaseComponent.onError(errorMessage, e); - } + if (prototypeMethod) { + retVal = prototypeMethod.apply(this, arguments); + } + if (classMethod !== prototypeMethod) { + retVal = classMethod.apply(this, arguments); } return retVal; @@ -261,11 +252,6 @@ function _makeSafe(obj: BaseComponent<{}, {}>, prototype: Object, methodName: st } } -BaseComponent.onError = (errorMessage: string) => { - console.error(errorMessage); - throw errorMessage; -}; - /** * Simple constant function for returning null, used to render empty templates in JSX. *