I use react with webpack. When I use a variable in my component like {props.children}
instead of this.props.children
the component fail silently. No errors is shown.
React does not swallow your exceptions so it must be something else.
Is there any chance you are using a Promise polyfill that doesn’t log unhandled rejections?
By the way we won’t be able to help unless you provide an example reproducing this.
I've bumped into this in the past when the call-stack from a Promise results in a reflow of React, catching any errors in the render process (to the best of my ability to debug, anyway). Is it possible that this is what is going on?
Edit: Sorry :(. This is what I get for skimming
@gaearon ran into this today!
class Baz extends React.Component {
render() {
return <div>Baz</div>
}
}
class Bar extends React.Component {
render() {
const { foo } = this.state; // Reference Error!
return <div>Bar</div>
}
}
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false
}
}
componentDidMount() {
Promise.resolve()
.then(() => {
this.setState({ loaded: true })
})
.catch(()=> {
console.log('Swallowed!')
});
}
render() {
const { loaded } = this.state;
return loaded ? <Bar /> : <Baz />;
}
}
ReactDOM.render(<Foo />, document.getElementById('root'));
^^ the example here will result in swallowed errors. wrapping the this.setState({loaded : true })
in a setTimeout results in the error not being swallowed:
class Baz extends React.Component {
render() {
return <div>Baz</div>
}
}
class Bar extends React.Component {
render() {
const { foo } = this.state; // Reference Error!
return <div>Bar</div>
}
}
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false
}
}
componentDidMount() {
Promise.resolve()
.then(() => {
setTimeout(() => this.setState({ loaded: true }));
})
.catch(()=> {
console.log('Not Swallowed!') ;
});
}
render() {
const { loaded } = this.state;
return loaded ? <Bar /> : <Baz />;
}
}
ReactDOM.render(<Foo />, document.getElementById('root'));
Is this my own ignorance with promises?
For your viewing pleasure: http://codepen.io/nickhudkins/pen/jrAamG
^^ the example here will result in swallowed errors
Yes, but you are swallowing them:
.then(() => {
this.setState({ loaded: true })
})
.catch(()=> {
console.log('Swallowed!')
});
Your catch()
handler is going to catch any error thrown in the then()
chain before it, including the one caused by a render()
due to a setState()
call.
Even if you don't use setState
directly, you may have the same problem if some other code you call uses it (for example, a Redux dispatch()
).
If you don’t want to catch errors resulting from setState()
, and want to only catch network failures (let’s imagine your Promise.resolve()
is actually a fetch()
), you want to use the second then()
argument instead:
componentDidMount() {
Promise.resolve()
.then(() => {
this.setState({ loaded: true })
}, (err) => {
console.log('An error occurred (but not in setState!)', err);
});
In this case, unless you catch()
later in the chain, the error in render()
will be uncaught and, with a good Promise polyfill (or with native Promises in Chrome and maybe other browsers), displayed.
I’m closing since there is no reproducible case.
If you can reproduce React swallowing an error, please file an issue with a case reproducing it.
Awesome. Thank you! I hadn't considered the fact that the setState resulted
in the throwing and therefore the catch handling it. I think you even
tweeted about this recently :(.
On Fri, Sep 16, 2016 at 5:13 PM Dan Abramov [email protected]
wrote:
I’m closing since there is no reproducible case.
If you can reproduce Reac swallowing an error, please file an issue with a
case reproducing it.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/react/issues/7617#issuecomment-247710118,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AASQdjn72jpNvMwq4fkzGct7SuxBffyEks5qqwZ6gaJpZM4Jw3vg
.
It’s hard to remember until you spend a few hours debugging it. Don’t worry 😉
@gaearon
Your catch() handler is going to catch any error thrown in the then() chain before it, including the one caused by a render() due to a setState() call.
I though setState was asynchronous? How could it work like that?
EDIT: Ahh it may be asynchronous. Goddamn it. Scratch the question.
It will likely be almost-always async in the future but there are cases when it can't be (e.g. inside an input event handler).
A small update on this. We just released React 16 beta which shouldn’t emit cryptic errors like this one. Even if the application code swallows an error, React 16 will still print it to the console. It might be too early for you to try React 16 (since ecosystem is still preparing for it), but this error should never occur in the future after you switch to it.
A small update on this. We just released React 16 beta which shouldn’t emit cryptic errors like this one. Even if the application code swallows an error, React 16 will still print it to the console. It might be too early for you to try React 16 (since ecosystem is still preparing for it), but this error should never occur in the future after you switch to it.
I am using React v16.9.0, yet I still came across this error. I was, however, able to find the problem.
Most helpful comment
Yes, but you are swallowing them:
Your
catch()
handler is going to catch any error thrown in thethen()
chain before it, including the one caused by arender()
due to asetState()
call.Even if you don't use
setState
directly, you may have the same problem if some other code you call uses it (for example, a Reduxdispatch()
).If you don’t want to catch errors resulting from
setState()
, and want to only catch network failures (let’s imagine yourPromise.resolve()
is actually afetch()
), you want to use the secondthen()
argument instead:In this case, unless you
catch()
later in the chain, the error inrender()
will be uncaught and, with a good Promise polyfill (or with native Promises in Chrome and maybe other browsers), displayed.