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

[DataStore] Invalid AWSPhone values cause silent failure when saving model to DynamoDB #1462

Open
1 task done
HuiSF opened this issue Aug 24, 2021 · 4 comments
Open
1 task done
Labels
api bug Something isn't working datastore DataStore category/plugins GraphQL API Related to the API (GraphQL) category/plugins

Comments

@HuiSF
Copy link
Member

HuiSF commented Aug 24, 2021

Before opening, please confirm:

Language and Async Model

Java, Kotlin

Amplify Categories

DataStore

Gradle script dependencies

// Put output below this line

dependencies {
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'com.amplifyframework:aws-api:1.24.1'
    implementation 'com.amplifyframework:aws-datastore:1.24.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Environment information

# Put output below this line
------------------------------------------------------------
Gradle 6.7.1
------------------------------------------------------------

Build time:   2020-11-16 17:09:24 UTC
Revision:     2972ff02f3210d2ceed2f1ea880f026acfbab5c0

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          1.8.0_292 (AdoptOpenJDK 25.292-b10)
OS:           Mac OS X 10.16 x86_64


Please include any relevant guides or documentation you're referencing

No response

Describe the bug

While using schemas with AWSPhone typed fields, if invalid phone numbers are provided, save API call succeeded, model saved into local DB, modal is not saved into DynamoDB due to DynamoDB value validation raised GraphQL error.

Expected behavior: save API call should return error with clear error message. Invalid data should not persisted in local DB.

Original issue: aws-amplify/amplify-flutter#822 (comment)
amplify-ios issue: aws-amplify/amplify-swift#1393

Schema example

type Person @model {
  id: ID!
  name: String!
  phone: AWSPhone
}

Reproduction steps (if applicable)

  1. create a minimal app using amplify-android with above listed schema
  2. Save model with invalid phone number
  3. Observe

Code Snippet

Java code example

        Person person = Person.builder()
                .name("Test with phone")
                .phone("1110004444")
                .build();
        Amplify.DataStore.save(person,
                success -> Log.i("Tutorial", "Saved item: " + success.item().getPhone()),
                error -> Log.e("Tutorial", "Could not save item to DataStore", error)
        );

Log output

// Put your logs below this line
I/Tutorial: Person {id=f153f9f6-f62d-4b65-8360-3f693cd1494e, name=Test with phone, department=null, phone=1110004444, createdAt=null, updatedAt=null}
I/Tutorial: Saved item: 1110004444
W/System.err: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
I/Tutorial: Record{id='d6ccd81c-051a-11ec-b8e4-4785562e7c29', containedModelId='f153f9f6-f62d-4b65-8360-3f693cd1494e', serializedMutationData='{"modelSchema":{"associations":{"department":{"associatedName":null,"associatedType":"Department","name":"BelongsTo","targetName":"departmentId"},"posts":{"associatedName":"author","associatedType":"Post","name":"HasMany","targetName":null}},"authRules":[],"fields":{"createdAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"createdAt","targetType":"AWSDateTime"},"department":{"authRules":[],"isArray":false,"isEnum":false,"isModel":true,"isReadOnly":false,"isRequired":false,"javaClassForValue":"com.amplifyframework.datastore.generated.model.Department","name":"department","targetType":"Department"},"id":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"id","targetType":"ID"},"name":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"name","targetType":"String"},"phone":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.lang.String","name":"phone","targetType":"AWSPhone"},"posts":{"authRules":[],"isArray":true,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.util.List","name":"posts","targetType":"Post"},"updatedAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"updatedAt","targetType":"AWSDateTime"}},"indexes":{"byDepartmentId":{"indexFieldNames":["departmentId"],"indexName":"byDepartmentId"}},"modelClass":"com.amplifyframework.datastore.generated.model.Person","name":"Person","pluralName":"People"},"mutatedItem":{"id":"f153f9f6-f62d-4b65-8360-3f693cd1494e","modelSchema":{"associations":{"department":{"associatedName":null,"associatedType":"Department","name":"BelongsTo","targetName":"departmentId"},"posts":{"associatedName":"author","associatedType":"Post","name":"HasMany","targetName":null}},"authRules":[],"fields":{"createdAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"createdAt","targetType":"AWSDateTime"},"department":{"authRules":[],"isArray":false,"isEnum":false,"isModel":true,"isReadOnly":false,"isRequired":false,"javaClassForValue":"com.amplifyframework.datastore.generated.model.Department","name":"department","targetType":"Department"},"id":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"id","targetType":"ID"},"name":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"name","targetType":"String"},"phone":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.lang.String","name":"phone","targetType":"AWSPhone"},"posts":{"authRules":[],"isArray":true,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.util.List","name":"posts","targetType":"Post"},"updatedAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"updatedAt","targetType":"AWSDateTime"}},"indexes":{"byDepartmentId":{"indexFieldNames":["departmentId"],"indexName":"byDepartmentId"}},"modelClass":"com.amplifyframework.datastore.generated.model.Person","name":"Person","pluralName":"People"},"serializedData":{"name":"Test w
I/amplify:aws-datastore: Successfully enqueued PendingMutation{mutatedItem=SerializedModel{id='f153f9f6-f62d-4b65-8360-3f693cd1494e', serializedData={name=Test with phone, createdAt=null, id=f153f9f6-f62d-4b65-8360-3f693cd1494e, phone=1110004444, updatedAt=null}, modelName=Person}, mutationType=CREATE, mutationId=d6ccd81c-051a-11ec-b8e4-4785562e7c29, predicate=MatchAllQueryPredicate}
I/Tutorial: Record{id='d6ccd81c-051a-11ec-b8e4-4785562e7c29', containedModelId='f153f9f6-f62d-4b65-8360-3f693cd1494e', serializedMutationData='{"modelSchema":{"associations":{"department":{"associatedName":null,"associatedType":"Department","name":"BelongsTo","targetName":"departmentId"},"posts":{"associatedName":"author","associatedType":"Post","name":"HasMany","targetName":null}},"authRules":[],"fields":{"createdAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"createdAt","targetType":"AWSDateTime"},"department":{"authRules":[],"isArray":false,"isEnum":false,"isModel":true,"isReadOnly":false,"isRequired":false,"javaClassForValue":"com.amplifyframework.datastore.generated.model.Department","name":"department","targetType":"Department"},"id":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"id","targetType":"ID"},"name":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"name","targetType":"String"},"phone":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.lang.String","name":"phone","targetType":"AWSPhone"},"posts":{"authRules":[],"isArray":true,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.util.List","name":"posts","targetType":"Post"},"updatedAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"updatedAt","targetType":"AWSDateTime"}},"indexes":{"byDepartmentId":{"indexFieldNames":["departmentId"],"indexName":"byDepartmentId"}},"modelClass":"com.amplifyframework.datastore.generated.model.Person","name":"Person","pluralName":"People"},"mutatedItem":{"id":"f153f9f6-f62d-4b65-8360-3f693cd1494e","modelSchema":{"associations":{"department":{"associatedName":null,"associatedType":"Department","name":"BelongsTo","targetName":"departmentId"},"posts":{"associatedName":"author","associatedType":"Post","name":"HasMany","targetName":null}},"authRules":[],"fields":{"createdAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"createdAt","targetType":"AWSDateTime"},"department":{"authRules":[],"isArray":false,"isEnum":false,"isModel":true,"isReadOnly":false,"isRequired":false,"javaClassForValue":"com.amplifyframework.datastore.generated.model.Department","name":"department","targetType":"Department"},"id":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"id","targetType":"ID"},"name":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":true,"javaClassForValue":"java.lang.String","name":"name","targetType":"String"},"phone":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.lang.String","name":"phone","targetType":"AWSPhone"},"posts":{"authRules":[],"isArray":true,"isEnum":false,"isModel":false,"isReadOnly":false,"isRequired":false,"javaClassForValue":"java.util.List","name":"posts","targetType":"Post"},"updatedAt":{"authRules":[],"isArray":false,"isEnum":false,"isModel":false,"isReadOnly":true,"isRequired":false,"javaClassForValue":"com.amplifyframework.core.model.temporal.Temporal$DateTime","name":"updatedAt","targetType":"AWSDateTime"}},"indexes":{"byDepartmentId":{"indexFieldNames":["departmentId"],"indexName":"byDepartmentId"}},"modelClass":"com.amplifyframework.datastore.generated.model.Person","name":"Person","pluralName":"People"},"serializedData":{"name":"Test w
I/amplify:aws-datastore: Successfully removed from mutations outboxPendingMutation{mutatedItem=SerializedModel{id='f153f9f6-f62d-4b65-8360-3f693cd1494e', serializedData={name=Test with phone, createdAt=null, id=f153f9f6-f62d-4b65-8360-3f693cd1494e, phone=1110004444, updatedAt=null}, modelName=Person}, mutationType=CREATE, mutationId=d6ccd81c-051a-11ec-b8e4-4785562e7c29, predicate=MatchAllQueryPredicate}


amplifyconfiguration.json

No response

GraphQL Schema

// Put your schema below this line

Additional information and screenshots

GraphQL request

{
	"query": "mutation CreatePerson($input: CreatePersonInput!) {\n  createPerson(input: $input) {\n    _deleted\n    _lastChangedAt\n    _version\n    createdAt\n    department {\n      id\n    }\n    id\n    name\n    phone\n    posts {\n      items {\n        id\n      }\n      nextToken\n      startedAt\n    }\n    updatedAt\n  }\n}\n",
	"variables": {
		"input": {
			"name": "Test with phone",
			"id": "f153f9f6-f62d-4b65-8360-3f693cd1494e",
			"phone": "1110004444"
		}
	}
}

GraphQL response

{
	"data": null,
	"errors": [{
		"path": null,
		"locations": [{
			"line": 1,
			"column": 23,
			"sourceName": null
		}],
		"message": "Variable 'phone' has an invalid value. Unable to parse `1110004444` as a valid phone number."
	}]
}
@rjuliano rjuliano added bug Something isn't working GraphQL API Related to the API (GraphQL) category/plugins datastore DataStore category/plugins labels Aug 25, 2021
@lawmicha
Copy link
Member

what is codegenerated? does the schema contain information that the phone is of type AWSPhone?

@HuiSF
Copy link
Member Author

HuiSF commented Aug 28, 2021

type Person @model {
  id: ID!
  name: String!
  phone: AWSPhone
}

The phone field type is string in codegen generated models (schema).

AWSPhone is used and validated within AppSync API.

@raphkim raphkim self-assigned this Sep 24, 2021
@chrisbonifacio
Copy link
Member

chrisbonifacio commented Jun 22, 2022

Related to aws-amplify/amplify-js#9065

@HuiSF Is the error handler/callback being triggered when you run into this issue?

@HuiSF
Copy link
Member Author

HuiSF commented Jun 22, 2022

No @chrisbonifacio error handler cannot capture this error due to this issue #1637 .

@lawmicha lawmicha added the api label Sep 7, 2022
@AnilMaktala AnilMaktala added feature-request Request a new feature p4 and removed p1 labels Oct 12, 2022
@mattcreaser mattcreaser removed the p4 label Jul 25, 2023
@ankpshah ankpshah removed the feature-request Request a new feature label Sep 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api bug Something isn't working datastore DataStore category/plugins GraphQL API Related to the API (GraphQL) category/plugins
Projects
None yet
Development

No branches or pull requests

8 participants