aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

DataStore.clear() can cause an unhandled runtime error #10230

Closed ptero closed 2 years ago

ptero commented 2 years ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

DataStore

Amplify Categories

api

Environment information

``` # Put output below this line System: OS: macOS 12.5 CPU: (8) arm64 Apple M1 Memory: 83.33 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 18.7.0 - /opt/homebrew/bin/node npm: 8.18.0 - /opt/homebrew/bin/npm Watchman: 2022.08.15.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 104.0.5112.101 Firefox: 101.0.1 Safari: 15.6 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/ui-react: ^3.2.1 => 3.4.1 @aws-amplify/ui-react-internal: undefined () @aws-amplify/ui-react-legacy: undefined () @babel/core: undefined () @babel/runtime: 7.15.4 @edge-runtime/primitives: 1.1.0-beta.10 @faker-js/faker: ^7.3.0 => 7.4.0 @hapi/accept: undefined () @headlessui/react: ^1.6.5 => 1.6.6 @heroicons/react: ^1.0.6 => 1.0.6 @napi-rs/triples: undefined () @next/react-dev-overlay: undefined () @pendulum-software/components: 0.2.03 => 0.2.03 @popperjs/core: ^2.11.5 => 2.11.6 @tailwindcss/forms: ^0.5.2 => 0.5.2 @tanstack/match-sorter-utils: ^8.1.1 => 8.1.1 @tanstack/react-table: ^8.1.3 => 8.5.11 @testing-library/jest-dom: ^5.16.5 => 5.16.5 @testing-library/react: ^13.3.0 => 13.3.0 @types/jest: ^28.1.6 => 28.1.7 @types/lodash: ^4.14.182 => 4.14.184 @types/node: 18.0.0 => 18.0.0 @types/react: 18.0.14 => 18.0.14 @types/react-dom: 18.0.5 => 18.0.5 @vercel/nft: undefined () acorn: undefined () amphtml-validator: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () autoprefixer: ^10.4.7 => 10.4.8 aws-amplify: ^4.3.30 => 4.3.32 babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () chalk: undefined () ci-info: undefined () cli-select: undefined () comment-json: undefined () compression: undefined () conf: undefined () constants-browserify: undefined () content-disposition: undefined () content-type: undefined () cookie: undefined () cross-spawn: undefined () crypto-browserify: undefined () cssnano-simple: undefined () debug: undefined () devalue: undefined () domain-browser: undefined () edge-runtime: undefined () eslint: 8.18.0 => 8.18.0 eslint-config-next: 12.2.0 => 12.2.0 eslint-plugin-react-hooks: ^4.6.0 => 4.6.0 etag: undefined () events: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () get-orientation: undefined () glob: undefined () gzip-size: undefined () http-proxy: undefined () https-browserify: undefined () icss-utils: undefined () ignore-loader: undefined () image-size: undefined () immutable: ^4.1.0 => 4.1.0 is-animated: undefined () is-docker: undefined () is-wsl: undefined () jest: ^28.1.3 => 28.1.3 jest-environment-jsdom: ^28.1.3 => 28.1.3 jest-worker: undefined () jotai: ^1.7.6 => 1.7.8 json5: undefined () jsonwebtoken: undefined () loader-utils: undefined () lodash: ^4.17.21 => 4.17.21 lodash.curry: undefined () lru-cache: undefined () micromatch: undefined () mini-css-extract-plugin: undefined () nanoid: undefined () native-url: undefined () neo-async: undefined () next: 12.2.0 => 12.2.0 next-i18next: ^11.0.0 => 11.3.0 next-i18next-create-client: undefined () next-pwa: ^5.5.4 => 5.5.5 node-fetch: undefined () node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () path-browserify: undefined () postcss: ^8.4.14 => 8.4.16 (8.4.5) postcss-flexbugs-fixes: undefined () postcss-modules-extract-imports: undefined () postcss-modules-local-by-default: undefined () postcss-modules-scope: undefined () postcss-modules-values: undefined () postcss-preset-env: undefined () postcss-safe-parser: undefined () postcss-scss: undefined () postcss-value-parser: undefined () prettier: ^2.7.1 => 2.7.1 prettier-plugin-tailwindcss: ^0.1.11 => 0.1.13 process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: 18.2.0 => 18.2.0 (18.0.0) react-dom: 18.2.0 => 18.2.0 react-hook-form: ^7.33.1 => 7.34.2 react-hot-toast: ^2.3.0 => 2.3.0 react-is: 17.0.2 react-phone-number-input: ^3.2.5 => 3.2.7 react-phone-number-input/commonjs: undefined () react-phone-number-input/core: undefined () react-phone-number-input/flags: undefined () react-phone-number-input/input-core: undefined () react-phone-number-input/input-max: undefined () react-phone-number-input/input-min: undefined () react-phone-number-input/input-mobile: undefined () react-phone-number-input/max: undefined () react-phone-number-input/min: undefined () react-phone-number-input/mobile: undefined () react-phone-number-input/react-hook-form: undefined () react-phone-number-input/react-hook-form-core: undefined () react-phone-number-input/react-hook-form-input: undefined () react-phone-number-input/react-hook-form-input-core: undefined () react-phone-number-input/react-native-input: undefined () react-popper: ^2.3.0 => 2.3.0 react-refresh: 0.12.0 react-responsive: ^9.0.0-beta.10 => 9.0.0-beta.10 react-server-dom-webpack: undefined () regenerator-runtime: 0.13.4 sass-loader: undefined () schema-utils: undefined () semver: undefined () send: undefined () setimmediate: undefined () source-map: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () tailwindcss: ^3.1.4 => 3.1.8 tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () tty-browserify: undefined () typescript: 4.7.4 => 4.7.4 ua-parser-js: undefined () unistore: undefined () util: undefined () vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () ```

Describe the bug

Calling DataStore.clear() can create an unhandled runtime error: TypeError: Cannot read properties of undefined (reading 'close')

Call Stack IndexedDBAdapter.eval node_modules/@aws-amplify/datastore/lib-esm/storage/adapter/IndexedDBAdapter.js (1063:0) step node_modules/@aws-amplify/datastore/lib-esm/storage/adapter/IndexedDBAdapter.js (32:0) Object.eval [as next] node_modules/@aws-amplify/datastore/lib-esm/storage/adapter/IndexedDBAdapter.js (13:45) fulfilled node_modules/@aws-amplify/datastore/lib-esm/storage/adapter/IndexedDBAdapter.js (4:42)

This seems to occur when DataStore.clear() is called before the DataStore is ready or DataStore.start() is called.

Expected behavior

DataStore.clear() should be safe to call no matter its status. I am trying to implement best practice by calling DataStore.clear() based on signIn and signOut auth Hub events.

Reproduction steps

  1. npx create-next-app@latest --typescript
  2. npm i aws-amplify
  3. amplify pull --appId d2kuwozgsh2xyn --envName dev
  4. Configure Amplify in pages/_app:
    
    import { Amplify } from "aws-amplify";

import awsconfig from "../src/aws-exports"; Amplify.configure(awsconfig);

5. Call DataStore.clear() from the Home page:
```javascript
import { DataStore } from "aws-amplify";

const Home: NextPage = () => {
  DataStore.clear();

Code Snippet

// Put your code below this line.
const onSignIn = Hub.listen("auth", async (data) => {
  if (
    data.payload.event === "signIn" ||
    data.payload.event === "autoSignIn"
  ) {
    await DataStore.clear(); // This can cause an error on sign in
    await DataStore.start();

    logger.info("Datastore cleared on sign in");
  }
 });

const onSignOut = Hub.listen("auth", async (data) => {
  if (
    data.payload.event === "signOut" ||
    data.payload.event === "autoSignIn_failure"
  ) {
    await DataStore.clear(); // This can cause an error on sign out
    logger.info("Datastore cleared on sign out");
  }
});

Log output

``` // Put your logs below this line > foo@0.1.0 dev > next dev ready - started server on 0.0.0.0:3000, url: http://localhost:3000 info - SWC minify release candidate enabled. https://nextjs.link/swcmin event - compiled client and server successfully in 1518 ms (1795 modules) wait - compiling... event - compiled client and server successfully in 150 ms (1795 modules) wait - compiling / (client and server)... event - compiled client and server successfully in 285 ms (1821 modules) [ERROR] 16:50.799 DataStore - Schema is not initialized. DataStore will not function as expected. This could happen if you have multiple versions of DataStore installed. Please see https://docs.amplify.aws/lib/troubleshooting/upgrading/q/platform/js/#check-for-duplicate-versions error - unhandledRejection: Error: Schema is not initialized. DataStore will not function as expected. This could happen if you have multiple versions of DataStore installed. Please see https://docs.amplify.aws/lib/troubleshooting/upgrading/q/platform/js/#check-for-duplicate-versions at checkSchemaInitialized (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:220:15) at DataStore. (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:1186:29) at step (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:44:23) at Object.next (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:25:53) at /Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:19:71 at new Promise () at __awaiter (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:15:12) at DataStore.clear (/Users/peter/Code/foo/node_modules/@aws-amplify/datastore/lib/datastore/datastore.js:1182:20) at Home (webpack-internal:///./pages/index.tsx:21:56) at renderWithHooks (/Users/peter/Code/foo/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5658:16) ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

dpilch commented 2 years ago

This appears to be an issue with just Next.js. I'm looking into the root cause now.

ptero commented 2 years ago

Thanks

alharris-at commented 2 years ago

@dpilch would this be resolved by the commit from Jon here https://github.com/aws-amplify/amplify-js/pull/10055?

dpilch commented 2 years ago

I was hitting some errors when testing with https://github.com/aws-amplify/amplify-js/pull/10055, but I think it may have been related to yarn link.

I know for certain that the one-liner change will fix this issue, but I will try testing with https://github.com/aws-amplify/amplify-js/pull/10055 again.

dpilch commented 2 years ago

I tested again with https://github.com/aws-amplify/amplify-js/pull/10055 and it doesn't fix the error. The change in https://github.com/aws-amplify/amplify-js/pull/10234 is needed.

salmanprk commented 2 years ago

I encountered a similar problem using "await DataStore.clear()" and "await DataStore.clear()" during Authentication but I received different error message. I was using SvelteKit for frontend.

dpilch commented 2 years ago

Hi @salmanprk, could you open another issue with the details of your error?