You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift异步函数中无法获取自定义APIError抛出响应问题

解决Swift Concurrency中自定义APIError无法正确传递的问题

问题原因

  1. LocalizedError协议实现错误:你重写了localizedDescription属性,但LocalizedError协议的标准属性是errorDescription,异步抛出错误时系统会优先读取errorDescription而非直接重写的localizedDescription,导致自定义错误信息不生效。
  2. 未捕获解码错误:原代码中解码失败时直接抛出JSONDecoder的原生错误,而非自定义的APIError.decodingError,导致这类错误无法触发你的自定义提示。
  3. 未提取关联值:resourceUnavailable case携带的状态码没有在错误信息中被提取,无法显示具体状态码。

解决方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:31:08