@@ -95,6 +95,8 @@ fun <D : Operation.Data> Operation<D>.parseJsonResponse(
95
95
* ```
96
96
*
97
97
* By default, this method does not close the [jsonReader]
98
+ *
99
+ * @see [toApolloResponse]
98
100
*/
99
101
@JvmOverloads
100
102
fun <D : Operation .Data > Operation<D>.parseResponse (
@@ -112,21 +114,24 @@ fun <D : Operation.Data> Operation<D>.parseResponse(
112
114
deferredFragmentIdentifiers,
113
115
)
114
116
} catch (throwable: Throwable ) {
115
- val apolloException = if (throwable is ApolloException ) {
116
- throwable
117
- } else {
118
- ApolloNetworkException (
119
- message = " Error while reading JSON response" ,
120
- platformCause = throwable
121
- )
122
- }
123
- return ApolloResponse .Builder (requestUuid = requestUuid ? : uuid4(), operation = this )
124
- .exception(exception = apolloException)
117
+ ApolloResponse .Builder (requestUuid = requestUuid ? : uuid4(), operation = this )
118
+ .exception(exception = throwable.wrapIfNeeded())
125
119
.isLast(true )
126
120
.build()
127
121
}
128
122
}
129
123
124
+ private fun Throwable.wrapIfNeeded (): ApolloException {
125
+ return if (this is ApolloException ) {
126
+ this
127
+ } else {
128
+ ApolloNetworkException (
129
+ message = " Error while reading JSON response" ,
130
+ platformCause = this
131
+ )
132
+ }
133
+ }
134
+
130
135
/* *
131
136
* writes a successful GraphQL Json response containing "data" to the given sink.
132
137
*
@@ -160,9 +165,12 @@ fun <D : Operation.Data> Operation<D>.composeJsonResponse(
160
165
}
161
166
162
167
/* *
163
- * Parses the [JsonReader] into an [ApolloResponse]
168
+ * Reads a single [ApolloResponse] from [this]. Returns an error response if [this] contains
169
+ * more than one JSON response or trailing tokens.
170
+ * [toApolloResponse] takes ownership and closes [this].
164
171
*
165
- * Warning: this closes the [JsonReader]. If you need to reuse it, use [parseResponse]
172
+ * @return the parsed [ApolloResponse]
173
+ * @see parseResponse
166
174
*/
167
175
@ApolloExperimental
168
176
fun <D : Operation .Data > JsonReader.toApolloResponse (
@@ -172,17 +180,54 @@ fun <D : Operation.Data> JsonReader.toApolloResponse(
172
180
deferredFragmentIdentifiers : Set <DeferredFragmentIdentifier >? = null,
173
181
): ApolloResponse <D > {
174
182
return use {
175
- operation.parseResponse(it, requestUuid, customScalarAdapters, deferredFragmentIdentifiers)
183
+ try {
184
+ ResponseParser .parse(
185
+ this ,
186
+ operation,
187
+ requestUuid,
188
+ customScalarAdapters,
189
+ deferredFragmentIdentifiers,
190
+ ).also {
191
+ if (peek() != JsonReader .Token .END_DOCUMENT ) {
192
+ throw JsonDataException (" Expected END_DOCUMENT but was ${peek()} " )
193
+ }
194
+ }
195
+ } catch (throwable: Throwable ) {
196
+ ApolloResponse .Builder (requestUuid = requestUuid ? : uuid4(), operation = operation)
197
+ .exception(exception = throwable.wrapIfNeeded())
198
+ .isLast(true )
199
+ .build()
200
+ }
176
201
}
177
202
}
178
203
204
+ /* *
205
+ * Reads a [ApolloResponse] from [this].
206
+ * The caller is responsible for closing [this].
207
+ *
208
+ * @return the parsed [ApolloResponse]
209
+ * @see [toApolloResponse]
210
+ */
179
211
@ApolloExperimental
180
212
fun <D : Operation .Data > JsonReader.parseResponse (
181
213
operation : Operation <D >,
182
214
requestUuid : Uuid ? = null,
183
215
customScalarAdapters : CustomScalarAdapters = CustomScalarAdapters .Empty ,
184
216
deferredFragmentIdentifiers : Set <DeferredFragmentIdentifier >? = null,
185
217
): ApolloResponse <D > {
186
- return operation.parseResponse(this , requestUuid, customScalarAdapters, deferredFragmentIdentifiers)
218
+ return try {
219
+ ResponseParser .parse(
220
+ this ,
221
+ operation,
222
+ requestUuid,
223
+ customScalarAdapters,
224
+ deferredFragmentIdentifiers,
225
+ )
226
+ } catch (throwable: Throwable ) {
227
+ ApolloResponse .Builder (requestUuid = requestUuid ? : uuid4(), operation = operation)
228
+ .exception(exception = throwable.wrapIfNeeded())
229
+ .isLast(true )
230
+ .build()
231
+ }
187
232
}
188
233
0 commit comments