Skip to content

Commit

Permalink
adds support for componentDidCatch() - minus the info argument be…
Browse files Browse the repository at this point in the history
…cause `preact`'s support for `componentDidCatch()` does not pass this argument (preactjs/preact#819 (comment))
  • Loading branch information
johnhaitas committed Nov 2, 2018
1 parent ef7b0a2 commit 33372ee
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,15 @@ function renderToString(vnode, context, opts, inner, isSvgMode) {
c._disable = c.__x = true;
c.props = props;
c.context = context;
if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
else if (c.componentWillMount) c.componentWillMount();
rendered = c.render(c.props, c.state, c.context);
try {
if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
else if (c.componentWillMount) c.componentWillMount();
rendered = c.render(c.props, c.state, c.context);
}
catch (error) {
if (c.componentDidCatch) c.componentDidCatch(error);
else throw error;
}

if (c.getChildContext) {
context = assign(assign({}, context), c.getChildContext());
Expand Down
64 changes: 64 additions & 0 deletions test/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -610,4 +610,68 @@ describe('render', () => {
expect(Bar).to.have.been.calledOnce.and.calledWithMatch({ count: 1 });
});
});

describe('Error Handling', () => {
it('should invoke componentDidCatch from an error thrown in getDerivedStateFromProps', () => {
const error = new Error();
class Test extends Component {
static getDerivedStateFromProps() {
throw error;
}
componentDidCatch(error) {}
}
spy(Test.prototype.constructor, 'getDerivedStateFromProps');
spy(Test.prototype, 'componentDidCatch');

render(<Test />);

expect(Test.prototype.constructor.getDerivedStateFromProps)
.to.have.been.calledOnce
.and.to.have.been.calledBefore(Test.prototype.componentDidCatch);

expect(Test.prototype.constructor.getDerivedStateFromProps)
.to.throw();
});

it('should invoke componentDidCatch from an error thrown in componentWillMount', () => {
class Test extends Component {
componentWillMount() {
throw new Error('Error in componentWillMount() method');
}
componentDidCatch(error) {}
}
spy(Test.prototype, 'componentWillMount');
spy(Test.prototype, 'componentDidCatch');

render(<Test />);

expect(Test.prototype.componentWillMount)
.to.have.been.calledOnce
.and.to.have.been.calledBefore(Test.prototype.componentDidCatch);

expect(Test.prototype.componentWillMount)
.to.throw();
});

it('should invoke componentDidCatch from an error thrown in render', () => {
class Test extends Component {
componentDidCatch(error) {}
render(props) {
throw new Error('Error in render() method');
return <div {...props} />; // eslint-disable-line
}
}
spy(Test.prototype, 'render');
spy(Test.prototype, 'componentDidCatch');

render(<Test />);

expect(Test.prototype.render)
.to.have.been.calledOnce
.and.to.have.been.calledBefore(Test.prototype.componentDidCatch);

expect(Test.prototype.render)
.to.throw();
});
});
});

0 comments on commit 33372ee

Please sign in to comment.