我正在使用 Crashlytics 编写错误记录器,但遇到了一个问题,这让我质疑我对协议和动态调度的理解。
使用 Crashlytics 记录非致命错误时,API 需要一个符合错误的对象和一个可选的用户信息字典。我目前正在查看 JSON 解码错误,当我刚刚在 recordError 中发送 DecodingError 时,我对在 Crashlytics 仪表板中看到的内容不太满意。所以我的解决方案是为 DecodingError 编写一个扩展,采用 CustomNSError 来提供一些更详细的信息,以帮助将来进行调试:
extension DecodingError: CustomNSError {
public static var errorDomain: String {
return "com.domain.App.ErrorDomain.DecodingError"
}
public var errorCode: Int {
switch self {
case .dataCorrupted:
return 1
case .keyNotFound:
return 2
case .typeMismatch:
return 3
case .valueNotFound:
return 4
}
}
public var errorUserInfo: [String : Any] {
switch self {
case .dataCorrupted(let context):
var userInfo: [String: Any] = [
"debugDescription": context.debugDescription,
"codingPath": context.codingPath.map { $0.stringValue }.joined(separator: ".")
]
guard let underlyingError = context.underlyingError else { return userInfo }
userInfo["underlyingErrorLocalizedDescription"] = underlyingError.localizedDescription
userInfo["underlyingErrorDebugDescription"] = (underlyingError as NSError).debugDescription
userInfo["underlyingErrorUserInfo"] = (underlyingError as NSError).userInfo.map {
return "\($0.key): \(String(describing: $0.value))"
}.joined(separator: ", ")
return userInfo
case .keyNotFound(let codingKey, let context):
return [
"debugDescription": context.debugDescription,
"codingPath": context.codingPath.map { $0.stringValue }.joined(separator: "."),
"codingKey": codingKey.stringValue
]
case .typeMismatch(_, let context), .valueNotFound(_, let context):
return [
"debugDescription": context.debugDescription,
"codingPath": context.codingPath.map { $0.stringValue }.joined(separator: ".")
]
}
}
}
我在记录器中编写了一个方法,如下所示:
func log(_ error: CustomNSError) {
Crashlytics.sharedInstance().recordError(error)
}
我在这里发送错误:
do {
let decoder = JSONDecoder()
let test = try decoder.decode(SomeObject.self, from: someShitJSON)
} catch(let error as DecodingError) {
switch error {
case .dataCorrupted(let context):
ErrorLogger.sharedInstance.log(error)
default:
break
}
}
但是传递给 log(_error:) 的对象不是我对 CustomNSError 的实现,它看起来像带有 NSCocoaErrorDomain 的标准 NSError。
我希望这足以解释我的意思,不知道为什么传递给日志的对象没有我在 DecodingError 的扩展中设置的值。我知道我可以轻松地在调用 Crashlytics 时单独发送额外的用户信息,但我很想知道我对这种情况的理解哪里出了问题。