iOS更优雅的NSError的处理流程

背景

Error的产生与传递基本上是贯穿我们整个APP开发,友好的错误提示,必要的error信息统计是很有必要,两年前改造我司的APM系统的时候就对error信息的上报做了一次重构。

一个典型的Error处理流程【优化前】
iOS更优雅的NSError的处理流程_第1张图片
image.png

第一个产生的Error为底层API函数产生,仅接着可能是的网络层,数据解析层,然后业务层,UI层都可能长生Error!

一次业务处理可能产生多个Error

问题:我们使用哪一个error呢?很多时候error信息保留不全要不就只保留了最后一个或自己定义一个。

思考一个问题

怎么能完整的按优先级按类型的把Error信息传递出来

优化后的Error处理流程

1.居于原始Error的基础上扩展带上,上一级的Error,使用的关键 NSUnderlyingErrorKey,存储结构图如下:
iOS更优雅的NSError的处理流程_第2张图片
image.png

实现可参考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.按调用层划分层错误类型
iOS更优雅的NSError的处理流程_第3张图片
image.png

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系统中各调用模块失败率,在其饼状图中一目了然。

我司系统一瞥

image.png

总结:规范的错误码,标准的错误划分,甚至是位置标记,都将极大的提高问题定位效率,提升代码质量。当然做好做完整远远不是真简单,但核心在这。

你可能感兴趣的:(iOS更优雅的NSError的处理流程)