swift-http-error-handling

在 Swift 中解释 HTTP 响应并处理失败。

Swift 5.9 Linux, visionOS 1, macOS 13, iOS 16, tvOS 16, watchOS 9 MIT License Automated Tests Workflow Status

概述

在 HTTP 协议中,客户端向服务器发送请求,服务器向客户端发回响应。 响应包含一个 状态码,以帮助客户端解释响应。

Foundation 这样的 HTTP 库将响应传递给调用者,而不将响应解释为成功或失败。 HTTPErrorHandling 可以帮助调用者解释 HTTP 响应并处理失败。

该模块适用于任何与 Swift 的 标准 HTTP 请求和响应类型兼容的 HTTP 库。 该模块可以单独用于直接使用 HTTP 库的代码中,或者可以作为更高级别的网络库的构建块使用。

表示 HTTP 应用程序失败

将 HTTP 响应解释为成功或失败后,需要一种方法来表示失败。 在 Swift 中,失败由符合 Error 协议的类型表示。 因此,该模块公开一个 HTTPApplicationError 类型来表示失败。

解释 HTTP 响应

该模块使用 throwIfFailed 方法扩展了 HTTPResponse,该方法将响应解释为成功或失败。 如果响应被解释为失败,则该方法抛出 HTTPApplicationError

一些 HTTP 服务器会将有关失败的更多详细信息添加到响应正文中。 throwIfFailed 方法允许将响应正文反序列化并附加到错误,以便以后可以访问其他失败详细信息。

重试 HTTP 请求

该模块扩展了 HTTPRequest 以添加对 RetryableRequest 的一致性,这是一个来自 swift-retry 包的协议,它将安全的重试方法添加到类型中。 安全的重试方法强制 HTTP 请求是 幂等的

重试方法实现会自动为 HTTPApplicationError 选择一个 RecoveryAction,使用 HTTP 特定的信息,包括失败是否是瞬时的,以及 Retry-After 标头的值(如果存在)。

使用 URLSession 的示例用法

import Foundation
import HTTPErrorHandling
import HTTPTypes
import HTTPTypesFoundation

let request = HTTPRequest(method: .get,
                          scheme: "https",
                          authority: "example.com",
                          path: "/")

let responseBody = try await request.retry { request in
   let (responseBody, response) = try await URLSession.shared.data(for: request)
   try response.throwIfFailed()
   return responseBody
}

有关更多示例,请参见文档