背景
Error的产生与传递基本上是贯穿我们整个APP开发,友好的错误提示,必要的error信息统计是很有必要,两年前改造我司的APM系统的时候就对error信息的上报做了一次重构。
一个典型的Error处理流程【优化前】
第一个产生的Error为底层API函数产生,仅接着可能是的网络层,数据解析层,然后业务层,UI层都可能长生Error!
一次业务处理可能产生多个Error
问题:我们使用哪一个error呢?很多时候error信息保留不全要不就只保留了最后一个或自己定义一个。
思考一个问题
怎么能完整的按优先级按类型的把Error信息传递出来
优化后的Error处理流程
1.居于原始Error的基础上扩展带上,上一级的Error,使用的关键 NSUnderlyingErrorKey,存储结构图如下:实现可参考AF库:
static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) {
if (!error) {
return underlyingError;
}
if (!underlyingError || error.userInfo[NSUnderlyingErrorKey]) {
return error;
}
NSMutableDictionary *mutableUserInfo = [error.userInfo mutableCopy];
mutableUserInfo[NSUnderlyingErrorKey] = underlyingError;
return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo];
}
2.按调用层划分层错误类型3.NSErorr最终构成
{
Domain: com.yourapp.UI
Code: 3XXX
...
UserInfo: {
Domain: com.yourapp.managerX
Code: 2XXX
…
UserInfo: {
Domain: com.yourapp.apiLib
Code: 1XXX
...
UserInfo: {
Domain: NSERLErrorDomain
Code: 403
...
}
}
}
}
收益
1.不丢失任何Error信息
2.方便调试,不管是本地log或者远程log带上全面的error信息。
3.根据Error Domain直观的定位问题模块,APM系统中各调用模块失败率,在其饼状图中一目了然。
我司系统一瞥
总结:规范的错误码,标准的错误划分,甚至是位置标记,都将极大的提高问题定位效率,提升代码质量。当然做好做完整远远不是真简单,但核心在这。