uppy
uppy copied to clipboard
Cannot read properties of null (reading 'componentWillLeave')
Initial checklist
- [X] I understand this is a bug report and questions should be posted in the Community Forum
- [X] I searched issues and couldn’t find anything (or linked relevant results below)
Error loacation
./node_modules/@uppy/informer/lib/TransitionGroup.js in a.performLeave at line 240:19
}
this.currentlyTransitioningKeys[key] = true;
const component = this.refs[key];
if (component.componentWillLeave) {
component.componentWillLeave(this._handleDoneLeaving.bind(this, key));
} else {
// Note that this is somewhat dangerous b/c it calls setState()
// again, effectively mutating the component before all the work
// is done.
Steps to reproduce
Randomly happens to users during upload init, and gets caught by our sentry error handling.
Expected behavior
error should be handled or check that component is still there before unmount.
Actual behavior
App crash
Hi @campmedia, thanks for the report. What version of Uppy are you using? And especially what version of @uppy/informer
? Do you know if it started to happen at some point or has always been there?
"@uppy/audio": "^0.3.1", "@uppy/aws-s3": "^2.0.9", "@uppy/aws-s3-multipart": "^2.2.1", "@uppy/core": "^2.1.8", "@uppy/dashboard": "^2.1.4", "@uppy/dropbox": "^2.0.5", "@uppy/facebook": "^2.0.5", "@uppy/golden-retriever": "^2.0.6", "@uppy/google-drive": "^2.0.5", "@uppy/instagram": "^2.0.5", "@uppy/react": "^2.1.2", "@uppy/url": "^2.0.5", "@uppy/utils": "^4.0.6", "@uppy/webcam": "^2.1.0",
This was the package versions when it occurred. Was also implemented using "Dashboard"
Without a way to reproduce the bug, it's going to be hard to fix it. If you are able to send a minimal repro / share a repo that reproduces the issue somewhat reliably, that'd be great! Otherwise we'll wait to see if someone else experience the issue and is able to share a repro.
Error location ./node_modules/@uppy/informer/lib/TransitionGroup.js
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'componentWillLeave') at TransitionGroup.performLeave (TransitionGroup.js?d8a3:240:1) at Array.forEach (<anonymous>) at TransitionGroup.componentDidUpdate (TransitionGroup.js?d8a3:157:1) at TransitionGroup.eval (preact.module.js?da65:1:5665) at eval (preact.module.js?da65:1:6556) at Array.some (<anonymous>) at eval (preact.module.js?da65:1:6520) at Array.some (<anonymous>) at z (preact.module.js?da65:1:6479) at P (preact.module.js?da65:1:8233)
I'm seeing this as well some small but not insignificant amount of times. I don't have a solid repro for it. but we're still using an older version @uppy/[email protected]
& @uppy/[email protected]
and haven't yet had the time to update to the v3 libraries.
I think I found the root cause for this.
We were using @uppy/[email protected]
and upgraded to @uppy/[email protected]
which is the latest and still have the issue.
Then managed to use a custom version of the informer which was a copy from the default but added some logging so this can help us reproduce it. We then found that all logging entries had one of these messages:
There was an error trying to leave uppy component with key: No Internet connection.
And currenlty transitioning keys: {"Connected to the Internet":true,"No Internet connection":true}.
And Keys to abort leave: [].
And Keys to enter: [].
And Keys to leave: [].
or:
There was an error trying to leave uppy component with key: No Internet connection.
And currenlty transitioning keys: {"No Internet connection":true}.
And Keys to abort leave: [].
And Keys to enter: [].
And Keys to leave: [].
Which means this happened when you had a poor internet connection. Looks like when the connection goes on and off repeatedly and in a short period of time, you experience this error. To reproduce it we executed this script in the browser console (having the dashboard open):
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function run() {
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(5);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(50);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(150);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(200);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(250);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(300);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(350);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(400);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(450);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(500);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(550);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(600);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(650);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(700);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(750);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
await sleep(800);
uppy.info(uppy.i18n('noInternetConnection'), 'error', 0);
}
run();
And that does the trick. Our first impulse is to replace all if (component.
for if (component?.
in the TransitionGroup file, which seems to be a fix for this, but there might be a better solution for it. Will create a PR for this.
Created a PR to address this: https://github.com/transloadit/uppy/pull/4410