Skip to content

fix: fix memoization #128

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

Merged
merged 1 commit into from
Mar 12, 2021
Merged

fix: fix memoization #128

merged 1 commit into from
Mar 12, 2021

Conversation

ehmicky
Copy link

@ehmicky ehmicky commented Mar 11, 2021

This fixes memoization of getNextConfig().

Note: the tests seem to be failing. Work in progress.

@ehmicky ehmicky added the type: bug code to address defects in shipped code label Mar 11, 2021
@ehmicky ehmicky self-assigned this Mar 11, 2021
Copy link

@jlengstorf jlengstorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@jlengstorf
Copy link

I'm thinking this test failure is due to the addition of a defaultFailBuild — the test can't override utils now, so it's throwing an actual error

@jlengstorf
Copy link

my new theory is that the memoization means the different next configs used in testing are no longer loaded due to returning the same promise

I started debugging this, but I ran into an issue where tests failed due to promises never resolving

I've run out of time to keep working on this, but for the record, here's where I ended up (tests still fail at this point)

first, I disabled memoization during tests:

  // Memoizes `nextConfig` except during test runs
  if (nextConfigPromise !== undefined && process.env.NODE_ENV !== 'test') {
    return await nextConfigPromise
  }

the code also moved the await out of the try/catch, so errors weren't throwing as expected. I moved it back in:

  let config
  try {
    nextConfigPromise = loadConfig(PHASE_PRODUCTION_BUILD, resolve('.'))
    config = await nextConfigPromise
  } catch (error) {
    return failBuild('Error loading your next.config.js.', { error })
  }

  return config

the tests at this point are failing with:

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "warn  - Detected next.config.js, no exported configuration found. https://err.sh/vercel/next.js/empty-configuration".

so I'm either doing something very obviously wrong (quite possible) or there's something tricky happening here that we haven't found yet

@ehmicky ehmicky force-pushed the fix/memoization branch 3 times, most recently from b2db4e5 to f42888e Compare March 12, 2021 16:03
@ehmicky ehmicky requested a review from jlengstorf March 12, 2021 16:04
@ehmicky
Copy link
Author

ehmicky commented Mar 12, 2021

Thanks for the additional debugging @jlengstorf, this really helped!
It turns out the problem was that:

  • When the promise returned by loadConfig() was rejected, memoized calls would not be wrapped by the try/catch block. In other words, the try/catch block should have covered the whole function, including the memoized if block.
  • Rejected promises should not be memoized.

I fixed those by using a proper memoization library instead, which correctly handles async functions. Tests are now passing 🎉

@@ -1,28 +1,29 @@
'use strict'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed by moize (otherwise, it throws).

}

const moizedGetNextConfig = moize(getNextConfigValue, { maxSize: 1e3, isPromise: true })
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxSize is required by moize@6. 1 would work in our case since the function has no arguments, but I used 1e3 so it covers future usage where we might add more arguments to this function.

Copy link

@jlengstorf jlengstorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! I'm adding this to my list of things to look at and figure out why your original solution didn't work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug code to address defects in shipped code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants