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

SwiftUI自定义错误附加追踪详情的标准实现方案问询

解决Swift自定义错误携带额外排查信息的方案

针对你需要在自定义错误中保存额外技术细节(比如解码缺失的key、上下文),同时给用户展示简洁提示的需求,有两种标准且实用的解决方式:

1. 给自定义错误枚举添加关联值(最常用)

Swift枚举支持关联值,刚好可以用来存储错误的额外细节,而且避开了“扩展不能添加存储属性”的限制——因为关联值是枚举本身的特性。

修改自定义错误枚举

把原来的apiDecodingError改成带关联值的case,用来保存解码错误的关键信息:

enum CustomError: Error {
    // 带关联值存储解码错误的具体信息
    case apiDecodingError(missingKey: String, context: DecodingError.Context)
    // 其他业务错误case示例
    case networkError(message: String)
}

扩展LocalizedError提供用户友好提示

保持扩展只负责返回用户可见的简洁提示,不处理技术细节:

extension CustomError: LocalizedError {
    var errorDescription: String? {
        switch self {
        case .apiDecodingError:
            return NSLocalizedString("Problem understanding service response.", comment: "")
        case .networkError(let message):
            return NSLocalizedString(message, comment: "")
        // 其他错误case的提示逻辑...
        }
    }
}

捕获原始错误并抛出自定义错误

在解码失败的场景,把原始错误的信息通过关联值传入自定义错误:

do {
    let decodedData = try JSONDecoder().decode(YourModel.self, from: responseData)
} catch let DecodingError.keyNotFound(key, context) {
    // 将缺失的key和上下文存入自定义错误
    throw CustomError.apiDecodingError(missingKey: key.stringValue, context: context)
} catch {
    throw CustomError.networkError(message: "Network request failed")
}

捕获自定义错误并提取技术细节上报

在最终的错误处理逻辑中,通过switch判断错误类型,取出关联值用于bug追踪:

do {
    try performAPIRequest()
} catch {
    // 给用户展示错误提示
    isAlertErrorPresented = true
    errorAlert = ErrorAlert(error: error)
    
    // 提取技术细节上报到bug追踪系统
    var trackingProperties = ["Error": error.localizedDescription]
    if let customError = error as? CustomError {
        switch customError {
        case .apiDecodingError(let missingKey, let context):
            trackingProperties["MissingKey"] = missingKey
            trackingProperties["DebugDescription"] = context.debugDescription
            trackingProperties["CodingPath"] = context.codingPath.map { $0.stringValue }.joined(separator: ".")
        case .networkError(let message):
            trackingProperties["NetworkMessage"] = message
        // 处理其他错误case...
        }
    }
    Analytics.trackEvent("UpdateNotificationSetting", withProperties: trackingProperties, flags: .critical)
}

2. 通用错误包装器(适合多类型错误统一处理)

如果你的项目中有多种原始错误需要包装,也可以创建一个通用的错误包装结构体,实现Error和LocalizedError协议,统一存储原始错误、用户提示和额外技术信息:

struct WrappedError: LocalizedError {
    let userMessage: String
    let originalError: Error?
    let technicalDetails: [String: Any]?
    
    var errorDescription: String? {
        return userMessage
    }
}

使用方式:包装原始错误

在捕获原始错误时,将其包装成WrappedError:

catch let DecodingError.keyNotFound(key, context) {
    let technicalDetails: [String: Any] = [
        "MissingKey": key.stringValue,
        "DebugDescription": context.debugDescription,
        "CodingPath": context.codingPath.map { $0.stringValue }.joined(".")
    ]
    throw WrappedError(
        userMessage: NSLocalizedString("Problem understanding service response.", comment: ""),
        originalError: error,
        technicalDetails: technicalDetails
    )
}

处理包装后的错误

catch let wrappedError as WrappedError {
    isAlertErrorPresented = true
    errorAlert = ErrorAlert(error: wrappedError)
    
    var trackingProperties = ["Error": wrappedError.userMessage]
    if let details = wrappedError.technicalDetails {
        properties.merge(details) { $1 }
    }
    Analytics.trackEvent("UpdateNotificationSetting", withProperties: trackingProperties, flags: .critical)
}

这两种方案都是Swift生态中处理这类需求的标准做法:第一种更适合针对特定业务错误做定制,第二种更适合统一管理所有错误的额外信息。

内容的提问来源于stack exchange,提问作者lcj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:20:25