错误处理
每次您执行一个GraphQL 操作 使用 Apollo Kotlin(或任何其他GraphQL 客户端),都可能出现以下两种类型的错误:
- 网络错误:由于与您的 GraphQL 服务器 实际通信时发生错误,没有收到 GraphQL 响应。这可能是 SSL 错误,您的应用程序离线时的套接字错误,或者 500 或任何其他 HTTP 错误。当发生网络错误时,不会返回任何数据。
- GraphQL 错误:已收到 GraphQL 响应,并且它包含非空内容
errors
字段。这意味着服务器无法完全处理 查询。响应可能包含 部分 数据,如果服务器能够处理 部分 的查询。
网络错误
网络错误抛出 ApolloException
。要处理它们,请在 query 中使用 try/catch
块:
try {val response = apolloClient.query(query).execute()} catch(exception: ApolloException) {// handle exception here}
原因
网络错误的可能原因包括(但不限于)
- 应用离线或无法访问网络。
- 出现DNS错误,无法查找宿主。
- 发生SSL错误(例如,服务器证书不受信任)。
- 连接被关闭。
- 服务器返回非成功的HTTP代码。
- 服务器没有返回有效的JSON。
- 响应JSON不符合模式且无法解析。
- 请求指定为CacheOnly但数据没有被缓存。
检查异常以获取有关实际错误的更详细信息。
GraphQL错误
因为 GraphQL 错误可能仍然包含数据,所以它们不会 抛出。相反,它们返回一个 Response
,其中包含一个 Response.errors
字段,指示发生的错误。
例如,以下 query 使用无效的 id
来查找 Person
:
query FilmAndPersonQuery {film(id: "ZmlsbXM6MQ==") {title}person(id: "badId") {name}}
服务器将发送以下响应
{"data": {"film": {"title": "A New Hope"},"person": null},"errors": [{"message": "No entry in local cache for https://swapi.dev/api/people/m�H/","locations": [{"line": 35,"column": 3}],"path": ["person"]}]}
请注意,尽管存在错误,但query 成功返回了电影的标题: A New Hope
。一般来说,如果在执行操作时出现任何错误,则错误会向下一个可空字段 吐出。向上冒泡 在这种情况下,person
是可空的。在最坏的情况下,如果其他所有内容都不是可空的,则response.data
可以是 null。
Apollo Kotlin 允许你访问Response 类中的数据和错误:
val response = try {apolloClient.query(query).execute()} catch(exception: ApolloException) {// Network error, not much to dothrow exception}// It's possible to display the film titleval title = response.data?.film?.titleif (title != null) {println(title)}// The person triggered an errorval person = response.data?.person?.nameif (person != null) {// do something with response.errors}
忽略部分数据
如果您不想要处理部分响应,则可以简化错误处理逻辑。ApolloResponse.dataAssertNoErrors
返回一个非可为空的 data
在有错误时抛出。这样,您可以在单个 catch {}
块中处理所有错误:
val data = try {apolloClient.query(query).execute().dataAssertNoErrors} catch(exception: ApolloException) {// All network or GraphQL errors are handled herethrow exception}// No need for safe calls on dataval title = data.film?.title
请注意,在 film
上仍需要安全调用,因为这个 字段 在 GraphQL模式中是可为空的类型。在代码生成中存在覆盖此情况的方法。有关更多详细信息,请了解 @nonnull
指令。