aws-amplify / aws-amplify/amplify-android
Fatal Exception in Http2Stream$FramingSource.read (DataStore / GraphQL)
- Dominant language
- Java
- Stars
- 287
- Forks
- 132
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 45
Description
### Before opening, please confirm:
- [X] I have [searched for duplicate or closed issues](https://github.com/aws-amplify/amplify-android/issues?q=is%3Aissue+) and [discussions](https://github.com/aws-amplify/amplify-android/discussions).
### Language and Async Model
Java
### Amplify Categories
GraphQL API, DataStore
### Gradle script dependencies
```groovy
implementation 'com.amplifyframework:aws-api:2.16.1'
implementation 'com.amplifyframework:aws-datastore:2.16.1'
```
### Environment information
```
------------------------------------------------------------
Gradle 8.0
------------------------------------------------------------
Build time: 2023-02-13 13:15:21 UTC
Revision: 62ab9b7c7f884426cf79fbedcf07658b2dbe9e97
Kotlin: 1.8.10
Groovy: 3.0.13
Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM: 17.0.6 (JetBrains s.r.o. 17.0.6+0-b2043.56-10027231)
OS: Windows 10 10.0 amd64
```
### Please include any relevant guides or documentation you're referencing
_No response_
### Describe the bug
In our production app, I'm seeing a crash happen occasionally with the Amplify AWS SDK for Android. The crash is a Fatal Exception from `io.reactivex.rxjava3.plugins.RxJavaPlugins.onError`. Full stack trace of the exception:
> Fatal Exception: ag.g
The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | DataStoreException{message=Failure performing sync query to AppSync., cause=ApiException{message=Could not retrieve the response body from the returned JSON, cause=mi.f0: stream was reset: CANCEL, recoverySuggestion=Sorry, we don’t have a recovery suggestion for this error.}, recoverySuggestion=Sorry, we don’t have a recovery suggestion for this error.}
Caused by com.amplifyframework.datastore.DataStoreException
Failure performing sync query to AppSync.
> com.amplifyframework.datastore.appsync.AppSyncClient.lambda$sync$0 (AppSyncClient.java:115)
com.amplifyframework.api.aws.AppSyncGraphQLOperation$OkHttpCallback.onResponse (AppSyncGraphQLOperation.java:138)
okhttp3.internal.connection.RealCall$AsyncCall.run (RealCall.kt:539)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:644)
java.lang.Thread.run (Thread.java:1012)
Caused by com.amplifyframework.api.ApiException
Could not retrieve the response body from the returned JSON
> com.amplifyframework.api.aws.AppSyncGraphQLOperation$OkHttpCallback.onResponse (AppSyncGraphQLOperation.java:138)
okhttp3.internal.connection.RealCall$AsyncCall.run (RealCall.kt:539)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:644)
java.lang.Thread.run (Thread.java:1012)
Caused by mi.f0
stream was reset: CANCEL
> okhttp3.internal.http2.Http2Stream$FramingSource.read (Http2Stream.kt:381)
okhttp3.internal.connection.Exchange$ResponseBodySource.read (Exchange.kt:281)
okio.RealBufferedSource.read (RealBufferedSource.kt:192)
okio.RealBufferedSource.request (RealBufferedSource.kt:209)
okio.RealBufferedSource.require (RealBufferedSource.kt:202)
okio.GzipSource.consumeHeader (GzipSource.kt:104)
okio.GzipSource.read (GzipSource.kt:62)
okio.RealBufferedSource.select (RealBufferedSource.kt:232)
okhttp3.internal._UtilJvmKt.readBomAsCharset (-UtilJvm.kt:89)
okhttp3.ResponseBody.string (ResponseBody.kt:72)
com.amplifyframework.api.aws.AppSyncGraphQLOperation$OkHttpCallback.onResponse (AppSyncGraphQLOperation.java:135)
okhttp3.internal.connection.RealCall$AsyncCall.run (RealCall.kt:539)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:644)
java.lang.Thread.run (Thread.java:1012)
It looks to me like there might be a try/catch block missing somewhere in the flow of this error (in the DataStore `com.amplifyframework.datastore` or the GraphQL API in `com.amplifyframework.api`).
This exception occurred for about 3% of users of our app, which is having a significant impact on the crash rate of our app. I would love your help -- please let me know if I can provide further details to help with solving this.
Not sure it's helpful but interestingly, 83% of the exceptions happen on Samsung phones, which is far from the distribution of device-type for our userbase. So there seems to be some relation between the crashes occurring more often on Samsung OS (although it does also happen on other not-customized OEMs like Google Pixels, but only about 1% of the crashes).
### Reproduction steps (if applicable)
_No response_
### Code Snippet
```java
// I'm pretty sure it's happening in the AWS Amplify SDK
```
### Log output
```
// Put your logs below this line
```
### amplifyconfiguration.json
_No response_
### GraphQL Schema
```graphql
// Put your schema below this line
```
### Additional information and screenshots
_No response_
Contributor guide
Research direction
Start with the stack-trace entry points in AppSyncGraphQLOperation.java at lines 135 and 138, then inspect AppSyncClient.java at line 115 and the surrounding DataStore sync flow. Use the reported OkHttp HTTP/2 CANCEL and RxJavaPlugins.onError path as the failing case; done should include a reproducible test or diagnosis showing how the failure is delivered without the reported fatal crash.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, graphql, java
- Domain
- api, database, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100