Swift异步函数中无法获取自定义APIError抛出响应问题
解决Swift Concurrency中自定义APIError无法正确传递的问题
问题原因
- LocalizedError协议实现错误:你重写了
localizedDescription属性,但LocalizedError协议的标准属性是errorDescription,异步抛出错误时系统会优先读取errorDescription而非直接重写的localizedDescription,导致自定义错误信息不生效。 - 未捕获解码错误:原代码中解码失败时直接抛出JSONDecoder的原生错误,而非自定义的
APIError.decodingError,导致这类错误无法触发你的自定义提示。 - 未提取关联值:
resourceUnavailablecase携带的状态码没有在错误信息中被提取,无法显示具体状态码。
解决方案
1. 修正LocalizedError扩展
实现LocalizedError协议要求的errorDescription属性,并在resourceUnavailable case中提取状态码:
extension APIError: LocalizedError { var errorDescription: String? { switch self { case .invalidPath: return "Invalid Path" case .decodingError: return "There was an error decoding the response" case .invalidServerResponse: return "Network request error." case .resourceUnavailable(let statusCode): return "Server or resource not available (Status Code: \(statusCode))" } } }
2. 捕获解码错误并抛出自定义错误
在getData函数中,用do-catch包裹解码操作,将原生解码错误转换为自定义的APIError.decodingError:
func getData<D: Decodable>(from endpoint: Route) async throws -> D { let request = try createRequest(from: endpoint) let response: NetworkResponse = try await session.data(for: request) guard let urlResponse = response.response as? HTTPURLResponse else { throw APIError.invalidServerResponse } let statusCode = urlResponse.statusCode guard (200...299).contains(statusCode) else { throw APIError.resourceUnavailable(statusCode) } do { return try decoder.decode(D.self, from: response.data) } catch { throw APIError.decodingError } }
3. 精准捕获自定义错误类型
在调用处优先捕获APIError类型,确保能正确获取自定义错误信息:
Task { do { let response: [PostsModel] = try await APIManager.shared.getData(from: .getCommentFromPost(postId: 1)) // 处理成功响应 } catch let apiError as APIError { print(apiError.localizedDescription) // 或直接使用apiError.errorDescription } catch { print("Unexpected error: \(error.localizedDescription)") } }
验证效果
现在当接口返回非2xx状态码时,会输出包含状态码的自定义错误信息;解码失败时会抛出decodingError对应的提示;其他自定义错误也能正常显示你设定的文本。
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

