Swift中自定义Error重写localizedDescription未生效问题排查
自定义Error的localizedDescription未正确触发的原因解析
代码示例
import Foundation enum OperationError: Error { case ioError(_ message: String) var localizedDescription: String { switch self { case .ioError(let message): return message } } } func test1() throws { throw OperationError.ioError("io error") } do { try test1() } catch { print("\(error) type: \(type(of: error))") print("\(error.localizedDescription)") print("\((error as? OperationError)?.localizedDescription ?? "")") }
输出结果
ioError("io error") type: OperationError The operation couldn’t be completed. (SwiftErrorDemo.OperationError error 0.) io error
原因分析
核心问题出在Swift原生Error协议本身不包含localizedDescription属性,这个属性是Foundation框架通过扩展给Error添加的默认实现。
- 你给
OperationError自定义的localizedDescription只是这个枚举的额外属性,并非Error协议要求的成员。 - 当捕获到的
error被当作Error类型处理时,编译器会调用Foundation提供的默认localizedDescription实现,生成通用的错误提示,也就是你看到的那串默认文本。 - 只有把
error强转为OperationError具体类型后,编译器才会找到你自定义的localizedDescription属性,此时才会返回你设置的自定义消息。
正确解决方案
让自定义错误遵循LocalizedError协议(Foundation提供的协议,专门用于定义本地化错误信息),实现协议要求的errorDescription属性,Foundation会自动用这个值来生成localizedDescription:
import Foundation enum OperationError: LocalizedError { case ioError(_ message: String) var errorDescription: String? { switch self { case .ioError(let message): return message } } } func test1() throws { throw OperationError.ioError("io error") } do { try test1() } catch { print("\(error) type: \(type(of: error))") print("\(error.localizedDescription)") print("\((error as? OperationError)?.localizedDescription ?? "")") }
此时输出会变为:
ioError("io error") type: OperationError io error io error
内容的提问来源于stack exchange,提问作者Itachi
相关产品推荐
相关产品推荐

