ios 如何将异常转换为NSError对象

pdkcd3nj  于 2023-01-03  发布在  iOS
关注(0)|答案(3)|浏览(132)

我希望将异常消息转换为NSError对象,以便可以在try-catch块中使用它(实际上我正在处理native iOS module for React Native)。

RCT_EXPORT_METHOD(myMethod:(NSDictionary *)dict
             resolver:(RCTPromiseResolveBlock)resolve
             rejecter:(RCTPromiseRejectBlock)reject)
{
  @try {
    // Do something which could throw something (NS Error or NS Exception)
    resolve(nil);
  } @catch (NSException *exception) {
    // HERE I WANT TO TRANSFORM THE EXCEPTION exception INTO AN ERROR error
    NSError error = ???
    reject(@"my_error", @"Could not do something important", error);
  }
}

我想将异常转换为NSError,因为reject函数的第三个参数(它拒绝JS端的Promise)期望输入为NSError类型。我不确定我的解决方案(使用try-catch)在此场景中是否是最好的。
this Apple Developer Guide中它说
您可以将异常转换为NSError对象,然后在警报面板中向用户显示error对象中的信息。
然而,本指南没有显示这方面的代码示例,而只显示了第二种方法的代码示例 * 您也可以在包含错误参数的方法中间接返回它们 *,这对我来说似乎很复杂。
那么,我如何将异常转换为NSError呢?The API reference of NSError似乎没有包含合适的函数。

j91ykkif

j91ykkif1#

无法将NSException转换为NSError,因为NSExceptionNSError的属性不同。是否有理由捕获NSException而不是构建**NSError机制?异常通常是致命的且不可恢复的,而错误则是非致命的且可恢复的。
如果您需要将NSException转换为NSError,您可以手动执行此操作,如下所示:

@try {
    // Something
} @catch (NSException *exception) {
    NSMutableDictionary * info = [NSMutableDictionary dictionary];
    [info setValue:exception.name forKey:@"ExceptionName"];
    [info setValue:exception.reason forKey:@"ExceptionReason"];
    [info setValue:exception.callStackReturnAddresses forKey:@"ExceptionCallStackReturnAddresses"];
    [info setValue:exception.callStackSymbols forKey:@"ExceptionCallStackSymbols"];
    [info setValue:exception.userInfo forKey:@"ExceptionUserInfo"];

    NSError *error = [[NSError alloc] initWithDomain:yourdomain code:errorcode userInfo:info];
    //use error
}
clj7thdc

clj7thdc2#

NSError是一个非常灵活的类,它允许一个非常可扩展的错误报告系统,因此没有人禁止你这样做:

/// NSExcetion * e = ...;
[NSError errorWithDomain:e.name code:0 userInfo:@{
    NSUnderlyingErrorKey: e,
    NSDebugDescriptionErrorKey: e.userInfo ?: @{ },
    NSLocalizedFailureReasonErrorKey: (e.reason ?: @"???") }];
}

头文件说明了NSUnderlyingErrorKey
此键的值应为NSError。
但是,should 不是 must,盲目地依赖于字典中找到的东西有一个特定类的代码一开始就被破坏了。该密钥的官方开发者文档没有这样说,并且该文档是权威的。
对于那些想知道e.userInfo ?: @{ }e.reason ?: @"???"是什么意思的人来说,这只是一种简短的写作方式:

e.reason != nil ? e.reason : @"???"

最后,代码可能会识别某些错误,并以特定的方式处理它们,但所有代码都必须编写为接受任何错误,甚至未知错误,并为这种情况提供某种默认处理。如果是您的代码,您知道错误域可能是一个异常名称,因此您可以检查该名称,第三方代码将只将其视为未知错误。

n6lpvg4x

n6lpvg4x3#

下面是我在代码中所做的事情:我的设计决定不是将异常“转换”为NSError,从而丢失其中的大部分信息,而是创建自己的NSError对象,表示“异常已经发生”,并将NSException中的数据嵌入到NSError中,如下所示:

NSError *err = nil;
    @try {
        //! ... Lot's of work done here...
    } 
    @catch (NSException *exception) {
        NSMutableDictionary *info = [exception.userInfo mutableCopy]?:[[NSMutableDictionary alloc] init];
        [info addEntriesFromDictionary: [exception dictionaryWithValuesForKeys:@[@"ExceptionName", @"ExceptionReason", @"ExceptionCallStackReturnAddresses", @"ExceptionCallStackSymbols"];
        [info addEntriesFromDictionary:@{NSLocalizedDescriptionKey: exception.name, NSLocalizedFailureReasonErrorKey:exception.reason }];
        err = [NSError errorWithDomain:@"myErrorDomain" code:-10 userInfo:info];
    } 
    @finally {
        //! --- wrap up and return --- 
    }

这将保留大多数异常信息,同时将一个具体的、可标识的NSError交给调用者。

相关问题