Skip to content

Commit d0df365

Browse files
authored
Add Swift interceptor iOS test and allow HttpInterceptor.intercept() to throw Throwable (#6403)
* add iOS test * crash * broaden the possible exceptions from HttpInterceptor.intercept() * the interceptor chain may also throw Throwable * use newer xcode
1 parent 023b47e commit d0df365

File tree

18 files changed

+726
-10
lines changed

18 files changed

+726
-10
lines changed

.github/workflows/pr.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,15 @@ jobs:
8787
with:
8888
name: tests-integration.zip
8989
path: diagnostics.zip
90-
90+
ios-tests:
91+
runs-on: macos-14
92+
steps:
93+
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
94+
- uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 #v4.2.1
95+
with:
96+
distribution: 'temurin'
97+
java-version: 17
98+
- run: /Applications/Xcode_16.2.0.app/Contents/Developer/usr/bin/xcodebuild -allowProvisioningUpdates -project tests/com.apollographql.iostest/com.apollographql.iostest.xcodeproj -configuration Debug -scheme com.apollographql.iostest -sdk iphoneos -destination name='iPhone 16' test -test-timeouts-enabled YES
9199
intellij-plugin:
92100
if: "!startsWith(github.head_ref, 'release-')"
93101
name: Build IntelliJ Plugin

libraries/apollo-runtime/src/appleMain/kotlin/com/apollographql/apollo/network/http/DefaultHttpEngine.apple.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.atomicfu.locks.withLock
1111
import kotlinx.cinterop.alloc
1212
import kotlinx.cinterop.nativeHeap
1313
import kotlinx.cinterop.ptr
14+
import kotlinx.coroutines.CancellationException
1415
import kotlinx.coroutines.suspendCancellableCoroutine
1516
import okio.Buffer
1617
import okio.BufferedSource

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo/network/http/HttpEngine.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.apollographql.apollo.api.http.HttpMethod
99
import com.apollographql.apollo.api.http.HttpRequest
1010
import com.apollographql.apollo.api.http.HttpResponse
1111
import com.apollographql.apollo.exception.ApolloNetworkException
12+
import kotlinx.coroutines.CancellationException
1213
import okio.Closeable
1314

1415
/**
@@ -23,6 +24,7 @@ interface HttpEngine : Closeable {
2324
*
2425
* @throws [ApolloNetworkException] if a network error happens
2526
*/
27+
@Throws(ApolloNetworkException::class, CancellationException::class)
2628
suspend fun execute(request: HttpRequest): HttpResponse
2729

2830
@ApolloDeprecatedSince(v4_0_0)

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo/network/http/HttpInterceptor.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@ package com.apollographql.apollo.network.http
22

33
import com.apollographql.apollo.api.http.HttpRequest
44
import com.apollographql.apollo.api.http.HttpResponse
5+
import com.apollographql.apollo.exception.ApolloException
56
import com.apollographql.apollo.exception.ApolloNetworkException
7+
import kotlinx.coroutines.CancellableContinuation
8+
import kotlinx.coroutines.CancellationException
69

710
interface HttpInterceptorChain {
811
/**
9-
* @throws [ApolloNetworkException] if a network error happens
12+
* Continues with the request and call all downstream interceptors.
1013
*/
14+
@Throws(Throwable::class)
1115
suspend fun proceed(request: HttpRequest): HttpResponse
1216
}
1317

1418
interface HttpInterceptor {
19+
/**
20+
* Intercepts the request and returns a response.
21+
* Implementation may throw in case of error. Those errors are typically
22+
* caught by the network transport and subsequently exposed in `ApolloResponse.exception`.
23+
* If the exception is not an instance of [ApolloException], it will be wrapped in an
24+
* instance of [ApolloNetworkException].
25+
*/
26+
@Throws(Throwable::class)
1527
suspend fun intercept(request: HttpRequest, chain: HttpInterceptorChain): HttpResponse
1628

1729
// TODO: remove dispose

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo/network/http/HttpNetworkTransport.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.apollographql.apollo.mpp.currentTimeMillis
2929
import com.apollographql.apollo.network.NetworkTransport
3030
import com.benasher44.uuid.Uuid
3131
import com.benasher44.uuid.uuid4
32+
import kotlinx.coroutines.CancellationException
3233
import kotlinx.coroutines.flow.Flow
3334
import kotlinx.coroutines.flow.catch
3435
import kotlinx.coroutines.flow.emitAll
@@ -62,20 +63,23 @@ private constructor(
6263
): Flow<ApolloResponse<D>> {
6364
return flow {
6465
val millisStart = currentTimeMillis()
65-
var apolloException: ApolloException? = null
66+
var throwable: Throwable? = null
6667
val httpResponse: HttpResponse? = try {
6768
DefaultHttpInterceptorChain(
6869
interceptors = interceptors + engineInterceptor,
6970
index = 0
7071
).proceed(httpRequest)
71-
} catch (e: ApolloException) {
72-
apolloException = e
72+
} catch (t: Throwable) {
73+
if (t is CancellationException) {
74+
throw t
75+
}
76+
throwable = t
7377
null
7478
}
7579

7680
val responses = when {
7781
httpResponse == null -> {
78-
flowOf(errorResponse(request.operation, apolloException!!))
82+
flowOf(errorResponse(request.operation, throwable!!))
7983
}
8084

8185
httpResponse.statusCode !in 200..299 && !httpResponse.isGraphQLResponse -> {
@@ -212,11 +216,11 @@ private constructor(
212216
if (jsonMerger == null) {
213217
jsonMerger = DeferredJsonMerger()
214218
}
215-
val merged = jsonMerger!!.merge(part)
216-
val deferredFragmentIds = jsonMerger!!.mergedFragmentIds
217-
val isLast = !jsonMerger!!.hasNext
219+
val merged = jsonMerger.merge(part)
220+
val deferredFragmentIds = jsonMerger.mergedFragmentIds
221+
val isLast = !jsonMerger.hasNext
218222

219-
if (jsonMerger!!.isEmptyPayload) {
223+
if (jsonMerger.isEmptyPayload) {
220224
null
221225
} else {
222226
@Suppress("DEPRECATION")

0 commit comments

Comments
 (0)