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

Source object is not a valid model inside handleNetworkStatus only #11306

Closed kevinsmith2 closed 1 year ago

kevinsmith2 commented 1 year ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication, DataStore, Storage, PubSub

Amplify Categories

auth, storage, function, api, hosting

Environment information

``` # Put output below this line System: OS: macOS 13.1 CPU: (10) arm64 Apple M1 Pro Memory: 463.50 MB / 32.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm Browsers: Chrome: 112.0.5615.137 npmPackages: @aws-sdk/client-dynamodb: ^3.315.0 => 3.316.0 @aws-sdk/client-s3: ^3.315.0 => 3.316.0 (3.6.1) @aws-sdk/client-sts: ^3.315.0 => 3.316.0 (3.186.0) @babel/cli: ^7.16.0 => 7.21.0 @babel/core: ^7.16.0 => 7.21.4 @babel/preset-env: ^7.16.4 => 7.21.4 @capacitor/android: 3.2.0 => 3.2.0 @capacitor/app: 1.1.1 => 1.1.1 @capacitor/browser: 1.0.7 => 1.0.7 @capacitor/cli: 3.2.0 => 3.2.0 @capacitor/core: 3.2.0 => 3.2.0 @capacitor/geolocation: 1.3.1 => 1.3.1 @capacitor/haptics: 1.1.4 => 1.1.4 @capacitor/ios: 3.2.0 => 3.2.0 @capacitor/keyboard: 1.2.3 => 1.2.3 @capacitor/network: 1.0.7 => 1.0.7 @capacitor/status-bar: 1.0.8 => 1.0.8 @datadog/browser-rum: ^4.39.0 => 4.39.0 @emotion/react: ^11.4.1 => 11.10.6 @emotion/styled: ^11.3.0 => 11.10.6 @fontsource/roboto: ^4.5.0 => 4.5.8 @googlemaps/js-api-loader: ^1.13.8 => 1.15.1 @ionic/core: ^7.0.3 => 7.0.3 @ionic/core/components: 0.0.0 @ionic/core/hydrate: undefined () @ionic/react: ^7.0.3 => 7.0.3 @ionic/react-router: ^7.0.3 => 7.0.3 @ionic/react-test-utils: ^0.4.0 => 0.4.0 @justinvartanian/capacitor-oauth2: ^3.0.3 => 3.0.3 @mui/base: ^5.0.0-alpha.90 => 5.0.0-alpha.126 @mui/icons-material: ^5.0.3 => 5.11.16 @mui/material: ^5.0.3 => 5.12.1 @mui/styles: ^5.0.1 => 5.12.0 @mui/x-date-pickers: ^5.0.0-beta.4 => 5.0.20 @testing-library/dom: ^9.2.0 => 9.2.0 (8.20.0) @testing-library/jest-dom: ^5.16.5 => 5.16.5 @testing-library/react: ^12 => 12.1.5 @testing-library/user-event: ^14.4.3 => 14.4.3 @turf/helpers: ^6.5.0 => 6.5.0 @turf/kinks: ^6.5.0 => 6.5.0 @types/jest: ^27 => 27.5.2 @types/lodash.debounce: ^4.0.7 => 4.0.7 @types/lodash.throttle: ^4.1.6 => 4.1.7 @types/node: ^18.15.11 => 18.15.12 @types/react: ^17.0.1 => 17.0.58 (16.14.40) @types/react-dom: ^16.9.10 => 16.9.18 @types/react-router: ^5.1.11 => 5.1.20 @types/react-router-dom: ^5.1.7 => 5.3.3 @types/react-window: ^1.8.5 => 1.8.5 @typescript-eslint/eslint-plugin: ^5.59.0 => 5.59.0 @typescript-eslint/parser: ^5.59.0 => 5.59.0 amazon-cognito-identity-js: ^5.2.2 => 5.2.14 auto-changelog: ^2.4.0 => 2.4.0 aws-amplify: ^4.3.11 => 4.3.46 date-fns: ^2.29.1 => 2.29.3 deep-object-diff: ^1.1.9 => 1.1.9 eslint: ^7.32.0 => 7.32.0 (8.38.0) eslint-config-airbnb: ^18.2.1 => 18.2.1 eslint-config-prettier: ^8.3.0 => 8.8.0 eslint-plugin-import: ^2.24.2 => 2.27.5 eslint-plugin-jsx-a11y: ^6.4.1 => 6.7.1 eslint-plugin-prettier: ^4.0.0 => 4.2.1 eslint-plugin-react: ^7.25.1 => 7.32.2 eslint-plugin-react-hooks: ^4.2.0 => 4.6.0 idb: ^6.1.5 => 6.1.5 (5.0.6, 7.1.1) ini: ^1.3.5 => 1.3.8 (3.0.1) inquirer: ^8.2.4 => 8.2.5 ionic-loader: undefined () ionicons: ^6.0.0 => 6.1.3 (7.1.0) ionicons-loader: undefined () ionicons/components: undefined () ionicons/icons: 6.1.3 (7.1.0) jest: ^29.2.2 => 29.5.0 (27.5.1) jsdom: ^20.0.1 => 20.0.3 (16.7.0) lodash.debounce: ^4.0.8 => 4.0.8 lodash.throttle: ^4.1.1 => 4.1.1 minimist: ^1.2.6 => 1.2.8 node-fetch: ^2.6.7 => 2.6.9 node-vault: ^0.9.22 => 0.9.22 nyc: ^15.1.0 => 15.1.0 ol: ^6.12.0 => 6.15.1 prettier: ^2.3.2 => 2.8.7 react: ^17.0.1 => 17.0.2 (18.2.0) react-collapsible: ^2.8.4 => 2.10.0 react-dom: ^17.0.1 => 17.0.2 react-imask: ^6.4.3 => 6.6.0 react-router: ^5.2.0 => 5.3.4 react-router-dom: ^5.2.0 => 5.3.4 react-scripts: ^5.0.1 => 5.0.1 react-window: ^1.8.7 => 1.8.9 replace-in-file: ^6.3.5 => 6.3.5 semver: ^7.3.7 => 7.5.0 (6.3.0, 5.7.1) shadow-dom-testing-library: ^1.2.0 => 1.10.0 styled-components: ^5.3.1 => 5.3.9 styled-components/macro: undefined () styled-components/native: undefined () styled-components/primitives: undefined () typescript: ^4.1.3 => 4.9.5 web-vitals: ^0.2.4 => 0.2.4 workbox-background-sync: ^6.5.4 => 6.5.4 workbox-broadcast-update: ^6.5.4 => 6.5.4 workbox-cacheable-response: ^6.5.4 => 6.5.4 workbox-core: ^6.5.4 => 6.5.4 workbox-expiration: ^6.5.4 => 6.5.4 workbox-google-analytics: ^6.5.4 => 6.5.4 workbox-navigation-preload: ^6.5.4 => 6.5.4 workbox-precaching: ^6.5.4 => 6.5.4 workbox-range-requests: ^6.5.4 => 6.5.4 workbox-routing: ^6.5.4 => 6.5.4 workbox-strategies: ^6.5.4 => 6.5.4 workbox-streams: ^6.5.4 => 6.5.4 npmGlobalPackages: corepack: 0.17.0 npm: 9.5.1 ```

Describe the bug

Trying to update from Node 14 to 18, I encountered a handful of issues. One issue was described on github with a fix here which worked in my datastore conflict handler. However, inside one of my React Context files there is a handleNetworkStatus function which updates records that were changed while the user was offline and this function doesn't accept the model and I have been unable to find a similar fix or apply that same logic to this area of code. Other functions within the same context file use the exact same object type in their DataStore.save call and have no problems.

Expected behavior

The DataStore.save call succeeds.

Reproduction steps

Starting with a React/Capacitor project which uses AppSync, DynamoDB, Lambdas, and NodeJS 14, update to NodeJS 18 and attempt to update a record which triggers code inside handleNetworkStatus.

Code Snippet

// TodoContext.tsx
// Both Todo.copyOf calls reference the same model in index.d.ts
const updateTodo = async (changed: MutableTodo) => {
...
        await DataStore.save( // this one works fine
          Todo.copyOf(original, (updated) => {
            const keys = Object.keys(updatedTodo).filter(
              (k: string) => !DATASTORE_IGNORE_FIELDS.includes(k)
            );
            for (let i = 0; i < keys.length; i += 1) {
              const key = keys[i] as keyof Trial;
              if (key !== 'crop') {
                updated[key as keyof Trial] = updatedTrial[key];
              }
...
function handleNetworkStatus(connected: boolean) {
...
        try {
          if (newInfo) {
            await DataStore.save(
              Todo.copyOf(todo, (updated) => { // error occurs here
                updated.info = newInfo;
              })
// index.d.ts
export declare type Todo = LazyLoading extends LazyLoadingDisabled ? EagerTodo : LazyTodo

export declare const Todo: (new (init: ModelInit<Todo, TodoMetaData>) => Todo) & {
  copyOf(source: Todo, mutator: (draft: MutableModel<Todo, TodoMetaData>) => MutableModel<Todo, TodoMetaData> | void): Todo;
}
// schema.graphql
type Trial
  @model
  @auth(
    rules: [
...
    ]
  ) {
  id: ID!
...
  info: Info,
}

Log output

``` // Put your logs below this line Updating info details for todo: Test0327.2 failed due to the following error: Error: The source object is not a valid model at Model.copyOf (datastore.js:523:1) at TodoContext.tsx:239:1 ```

aws-exports.js

/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "us-east-2",
    "aws_appsync_graphqlEndpoint": "https://r5udgk24nfekvmbu3hn5wdb7xa.appsync-api.us-east-2.amazonaws.com/graphql",
    "aws_appsync_region": "us-east-2",
    "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
    "aws_appsync_apiKey": "da2-l5nudzpen5h3boaqljl35fezom",
    "aws_cloud_logic_custom": [
        {
            "name": "keysApi",
            "endpoint": "x",
            "region": "us-east-2"
        }
    ],
    "aws_cognito_identity_pool_id": "us-east-2:3b3cdeb4-3f80-476f-bc13-1bd7f1eb4a04",
    "aws_cognito_region": "us-east-2",
    "aws_user_pools_id": "us-east-2_OKkveba9K",
    "aws_user_pools_web_client_id": "30blsiv4u0nem5lo45gtqacq0n",
    "oauth": {
        "domain": "comt-dev.auth.us-east-2.amazoncognito.com"
    },
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": [
            "REQUIRES_LOWERCASE",
            "REQUIRES_UPPERCASE",
            "REQUIRES_NUMBERS",
            "REQUIRES_SYMBOLS"
        ]
    },
    "aws_cognito_verification_mechanisms": [],
    "aws_user_files_s3_bucket": "x",
    "aws_user_files_s3_bucket_region": "us-east-2"
};

export default awsmobile;

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

I didn't write this code and those who did have moved on but I have done my best to include enough non-identifiable information about the code and the error.

kevinsmith2 commented 1 year ago

I found some legacy data causing this issue, closing.