Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import error inside async loaded component is hidden by @loadable #420

Closed
mschipperheyn opened this issue Aug 27, 2019 · 11 comments
Closed

Comments

@mschipperheyn
Copy link

🐛 Bug Report

So, just spent a couple of hours debugging this vague error

loadable.esm.js:269 Uncaught TypeError: Cannot convert undefined or null to object
    at getPrototypeOf (<anonymous>)
    at hoistNonReactStatics (hoist-non-react-statics.cjs.js:71)
    at resolveComponent (loadable.esm.js:326)
    at InnerLoadable.loadSync (loadable.esm.js:183)
    at new InnerLoadable (loadable.esm.js:132)
    at constructClassInstance (react-dom.development.js:13308)
    at updateClassComponent (react-dom.development.js:16985)
    at beginWork$1 (react-dom.development.js:18505)
    at HTMLUnknownElement.callCallback (react-dom.development.js:347)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:397)
    at invokeGuardedCallback (react-dom.development.js:454)
    at beginWork$$1 (react-dom.development.js:23217)
    at performUnitOfWork (react-dom.development.js:22208)
    at workLoopSync (react-dom.development.js:22185)
    at renderRoot (react-dom.development.js:21878)
    at runRootCallback (react-dom.development.js:21554)
    at eval (react-dom.development.js:11353)
    at unstable_runWithPriority (scheduler.development.js:643)
    at runWithPriority$2 (react-dom.development.js:11305)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11349)
    at flushSyncCallbackQueue (react-dom.development.js:11338)
    at scheduleUpdateOnFiber (react-dom.development.js:21431)
    at dispatchAction (react-dom.development.js:15816)
    at Object.next (react-hooks.esm.js:215)
    at notifySubscription (Observable.js:130)
    at onNotify (Observable.js:165)
    at SubscriptionObserver.next (Observable.js:219)
    at eval (bundle.esm.js:435)
    at Array.forEach (<anonymous>)
    at iterateObserversSafely (bundle.esm.js:435)
    at Object.next (bundle.esm.js:410)
    at invoke (bundle.esm.js:1209)
    at eval (bundle.esm.js:1294)
    at eval (bundle.esm.js:1559)
    at Set.forEach (<anonymous>)
    at eval (bundle.esm.js:1557)
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (bundle.esm.js:1555)
    at eval (bundle.esm.js:1646)
    at Object.next (Observable.js:308)
    at notifySubscription (Observable.js:130)
    at onNotify (Observable.js:165)
    at SubscriptionObserver.next (Observable.js:219)
    at eval (bundle.esm.js:866)
    at Set.forEach (<anonymous>)
    at Object.next (bundle.esm.js:866)
    at notifySubscription (Observable.js:130)
    at onNotify (Observable.js:165)
    at SubscriptionObserver.next (Observable.js:219)
    at Object.RetryableOperation.onNext [as next] (bundle.esm.js:44)
The above error occurred in the <InnerLoadable> component:
    in InnerLoadable (created by Context.Consumer)
    in Unknown (created by ForwardRef)
    in ForwardRef (at accountRoutes.js:58)
    in component (at PrivateRoute.js:81)
    in Route (at PrivateRoute.js:81)
    in Query (at SimpleQuery.js:16)
    in SimpleQuery (at PrivateRoute.js:40)
    in PrivateRoute (created by Context.Consumer)
    in withRouter(PrivateRoute) (at accountRoutes.js:54)
    in Switch (at accountRoutes.js:27)
    in Routes (at PrivateRoute.js:81)
    in Route (at PrivateRoute.js:81)
    in Query (at SimpleQuery.js:16)
    in SimpleQuery (at PrivateRoute.js:40)
    in PrivateRoute (created by Context.Consumer)
    in withRouter(PrivateRoute) (at AccountRoutes/index.js:26)
    in Switch (at AccountRoutes/index.js:22)
    in CaptureRouteNotFound (created by Context.Consumer)
    in withRouter(CaptureRouteNotFound) (at AccountRoutes/index.js:21)
    in ScrollToTop (created by Context.Consumer)
    in withRouter(ScrollToTop) (at AccountRoutes/index.js:20)
    in div (at AccountRoutes/index.js:19)
    in ErrorBoundary (created by WithStyles(ErrorBoundary))
    in WithStyles(ErrorBoundary) (at Layout.js:47)
    in main (at Layout.js:42)
    in div (at Layout.js:35)
    in Query (at SimpleQuery.js:16)
    in SimpleQuery (at Layout.js:29)
    in Layout (created by WithStyles(Layout))
    in WithStyles(Layout) (created by Context.Consumer)
    in withRouter(WithStyles(Layout)) (at AccountRoutes/index.js:17)
    in AccountRoutes (created by Context.Consumer)
    in Route (at Routes/index.js:19)
    in Switch (at Routes/index.js:13)
    in Routes (at router/index.js:21)
    in ErrorBoundary (created by WithStyles(ErrorBoundary))
    in WithStyles(ErrorBoundary) (at router/index.js:9)
    in Home (created by Context.Consumer)
    in withRouter(Home) (at App.js:24)
    in AppContextProvider (at App.js:23)
    in I18nProvider (at App.js:22)
    in App (at client.js:33)
    in Provider (at client.js:32)
    in Router (created by BrowserRouter)
    in BrowserRouter (at client.js:31)
    in ThemeProvider (at Theme.js:11)
    in Theme (at client.js:30)
    in Provider (at client.js:29)
    in ApolloProvider (at client.js:28)

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
console.<computed> @ index.js:1
logCapturedError @ react-dom.development.js:19814
logError @ react-dom.development.js:19850
callback @ react-dom.development.js:20961
callCallback @ react-dom.development.js:12929
commitUpdateEffects @ react-dom.development.js:12968
commitUpdateQueue @ react-dom.development.js:12959
commitLifeCycles @ react-dom.development.js:20079
commitLayoutEffects @ react-dom.development.js:22813
callCallback @ react-dom.development.js:347
invokeGuardedCallbackDev @ react-dom.development.js:397
invokeGuardedCallback @ react-dom.development.js:454
commitRootImpl @ react-dom.development.js:22585
unstable_runWithPriority @ scheduler.development.js:643
runWithPriority$2 @ react-dom.development.js:11305
commitRoot @ react-dom.development.js:22414
runRootCallback @ react-dom.development.js:21554
(anonymous) @ react-dom.development.js:11353
unstable_runWithPriority @ scheduler.development.js:643
runWithPriority$2 @ react-dom.development.js:11305
flushSyncCallbackQueueImpl @ react-dom.development.js:11349
flushSyncCallbackQueue @ react-dom.development.js:11338
scheduleUpdateOnFiber @ react-dom.development.js:21431
dispatchAction @ react-dom.development.js:15816
next @ react-hooks.esm.js:215
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
(anonymous) @ bundle.esm.js:435
iterateObserversSafely @ bundle.esm.js:435
next @ bundle.esm.js:410
invoke @ bundle.esm.js:1209
(anonymous) @ bundle.esm.js:1294
(anonymous) @ bundle.esm.js:1559
(anonymous) @ bundle.esm.js:1557
QueryManager.broadcastQueries @ bundle.esm.js:1555
(anonymous) @ bundle.esm.js:1646
next @ Observable.js:308
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
(anonymous) @ bundle.esm.js:866
next @ bundle.esm.js:866
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
RetryableOperation.onNext @ bundle.esm.js:44
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
next @ bundle.esm.js:29
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
next @ Observable.js:312
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
(anonymous) @ bundle.esm.js:85
(anonymous) @ bundle.esm.js:85
next @ bundle.esm.js:83
notifySubscription @ Observable.js:130
onNotify @ Observable.js:165
next @ Observable.js:219
(anonymous) @ bundle.esm.js:74
Promise.then (async)
(anonymous) @ bundle.esm.js:73
Subscription @ Observable.js:183
subscribe @ Observable.js:262
OperationBatcher.consumeQueue @ bundle.esm.js:73
(anonymous) @ bundle.esm.js:106
setTimeout (async)
OperationBatcher.scheduleQueueConsumption @ bundle.esm.js:103
(anonymous) @ bundle.esm.js:37
Subscription @ Observable.js:183
subscribe @ Observable.js:262
(anonymous) @ bundle.esm.js:13
Promise.then (async)
(anonymous) @ bundle.esm.js:12
Subscription @ Observable.js:183
subscribe @ Observable.js:262
(anonymous) @ Observable.js:305
Subscription @ Observable.js:183
subscribe @ Observable.js:262
(anonymous) @ bundle.esm.js:11
Subscription @ Observable.js:183
subscribe @ Observable.js:262
RetryableOperation.try @ bundle.esm.js:122
RetryableOperation.start @ bundle.esm.js:110
RetryLink.request @ bundle.esm.js:153
(anonymous) @ bundle.esm.js:160
(anonymous) @ bundle.esm.js:160
(anonymous) @ bundle.esm.js:160
(anonymous) @ bundle.esm.js:155
execute @ bundle.esm.js:187
QueryManager.getObservableFromLink @ bundle.esm.js:1588
(anonymous) @ bundle.esm.js:1630
QueryManager.fetchRequest @ bundle.esm.js:1629
(anonymous) @ bundle.esm.js:1146
step @ tslib.es6.js:99
(anonymous) @ tslib.es6.js:80
(anonymous) @ tslib.es6.js:73
__awaiter @ tslib.es6.js:69
QueryManager.fetchQuery @ bundle.esm.js:1092
QueryManager.observeQuery @ bundle.esm.js:1460
ObservableQuery.setUpQuery @ bundle.esm.js:388
ObservableQuery.onSubscribe @ bundle.esm.js:366
(anonymous) @ bundle.esm.js:96
Subscription @ Observable.js:183
subscribe @ Observable.js:262
QueryData.startQuerySubscription @ react-hooks.esm.js:206
QueryData._this.getExecuteResult @ react-hooks.esm.js:72
QueryData.execute @ react-hooks.esm.js:88
(anonymous) @ react-hooks.esm.js:347
useDeepMemo @ react-hooks.esm.js:321
useBaseQuery @ react-hooks.esm.js:347
useQuery @ react-hooks.esm.js:356
Query @ react-components.esm.js:8
renderWithHooks @ react-dom.development.js:15108
mountIndeterminateComponent @ react-dom.development.js:17342
beginWork$1 @ react-dom.development.js:18486
beginWork$$1 @ react-dom.development.js:23193
performUnitOfWork @ react-dom.development.js:22208
workLoopSync @ react-dom.development.js:22185
renderRoot @ react-dom.development.js:21878
scheduleUpdateOnFiber @ react-dom.development.js:21419
scheduleRootUpdate @ react-dom.development.js:24319
updateContainerAtExpirationTime @ react-dom.development.js:24347
updateContainer @ react-dom.development.js:24436
(anonymous) @ react-dom.development.js:24963
unbatchedUpdates @ react-dom.development.js:21687
legacyRenderSubtreeIntoContainer @ react-dom.development.js:24962
hydrate @ react-dom.development.js:25029
(anonymous) @ client.js:60
checkReadyState @ loadable.esm.js:425
(anonymous) @ loadable.esm.js:435
loadableReady @ loadable.esm.js:410
(anonymous) @ client.js:23
./src/client.js @ client.chunk.js:6449
__webpack_require__ @ bundle.js:786
fn @ bundle.js:151
1 @ client.chunk.js:12567
__webpack_require__ @ bundle.js:786
checkDeferredModules @ bundle.js:46
webpackJsonpCallback @ bundle.js:33
(anonymous) @ client.chunk.js:1
Show 106 more frames
index.js:1 Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://fb.me/react-crossorigin-error for more information.
    at Object.invokeGuardedCallbackDev (react-dom.development.js:408)
    at invokeGuardedCallback (react-dom.development.js:454)
    at beginWork$$1 (react-dom.development.js:23217)
    at performUnitOfWork (react-dom.development.js:22208)
    at workLoopSync (react-dom.development.js:22185)
    at renderRoot (react-dom.development.js:21878)
    at runRootCallback (react-dom.development.js:21554)
    at eval (react-dom.development.js:11353)
    at unstable_runWithPriority (scheduler.development.js:643)

Not very actionable and very hard to understand. Until you start looking inside loadable.esm
To my surprise, I found this error there:

"ReferenceError: EMAIL_FRAGMENT is not defined
    at eval (webpack-internal:///./src/shared/modules/sorteio/graphql.js:140:94)
    at Module../src/shared/modules/sorteio/graphql.js 
[...]

It was a Graphql gql string that imported ${EMAIL_FRAGMENT} which didn't exist.

A 2 seconds fix. If you encounter an error like this, do a debugger break at the error catch in loadable and you will see what's going on.

To Reproduce

Not sure if this is easily reproducible. It might be related to the hierarchy of babel plugins I use.

The component in question was loaded by react-router through @loadable/component.

Expected behavior

The actual error should bubble to the top.

Link to repl or repo (highly encouraged)

Run npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard

Paste the results here:

## System:
 - OS: macOS 10.14.6
 - CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
 - Memory: 148.71 MB / 16.00 GB
 - Shell: 3.2.57 - /bin/bash
## Binaries:
 - Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
 - Yarn: 1.17.3 - ~/.nvm/versions/node/v10.16.3/bin/yarn
 - npm: 6.9.0 - ~/.nvm/versions/node/v10.16.3/bin/npm
 - Watchman: 4.9.0 - /usr/local/bin/watchman
@theKashey
Copy link
Collaborator

Loadable thinks that component is "ready", as long as it present in the webpack module cache, and tries to use it.
However, it is not present. It's not absolutely clear why module export was broken (that's why you got the error), but it haven't broke your whole application.

That might be the problem:

  • load loadable
  • loadAsync
  • run time exception, reject, set error state
  • suspense more is active, so error would be thrown, and react would recreate loadable. Look like you don't have proper ErrorBoundary set up.
  • loadable checks isReady in the constructor, and it is(by also broken), tries to loadSync, this error.

In short - there is a bug handling non-network exceptions. However - without React recreating

@gregberge
Copy link
Owner

@theKashey can we do something to fix it in loadable?

@theKashey
Copy link
Collaborator

I could think only about one solution:

  • loadAsync
  • catch an error
  • check if the module is "ready". That means - this is not network error, but run time error after module load, and we could not nor recover from it(only delete webpack module cache), nor stand as described in the issue. <<-----
  • so console.error it to let the user know <<-----
  • (optional) mark location as "broken", and throw the "right" error next time React will render you.
  • (optional) do not throw error in this case, as long as it would not help, but display the error.

@gregberge
Copy link
Owner

Could you submit a PR to fix it?

@gregberge gregberge added the bug label Aug 28, 2019
@theKashey
Copy link
Collaborator

Not to "fix", but to "soften"

@DavideDaniel
Copy link

DavideDaniel commented Oct 27, 2019

I ran into this bug while mixing loadable and lazy - main routes were loaded with loadable and in the code path was also a lazy component which kept showing the error mentioned by the original post. I haven't been able to get lazy to work within our ssr app yet, but will update with more findings at some point.

Update:
This was largely happening due to our implementation of SSR. We were running babel over src dir and then webpacking the client from the src dir as well. The problem was the shared code would get run over by the babel plugin and would not work as expected with the webpack plugin. Separating the server code out of src dir got SSR + async route loading + component splitting working.

Thank you =)

@mschipperheyn
Copy link
Author

@FavideDaniel Interesting! So, you created a new package for front end code?

@DavideDaniel
Copy link

DavideDaniel commented Oct 31, 2019

@FavideDaniel Interesting! So, you created a new package for front end code?

Um.. I was working on solving a problem at work and it's code that existed prior to the days of solutions such as razzle or next.js. Our specific issue was the conflating of babel + webpack which inadvertently touch the isomorphic code in a way where the evaluation of the webpacked code was running into problems. I did not create a package to solve this. I would consider our issue to be a side-effect of carrying on tech debt. I tackled the issue by tackling that debt, which was to not run babel over code unnecessarily. I moved all the server code away from client code and re-wrote the import and export statements in commonjs.

@stale
Copy link

stale bot commented Jan 9, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jan 9, 2020
@stale stale bot closed this as completed Jan 16, 2020
@ljwagerfield
Copy link

I was accidentally exporting non-default exports, but was treating them as default exports with the import(...) call.

The solution for me was to change my named exports to default exports.

@jottenlips
Copy link

default export worked for me too! thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants