如何将异常转换为 NSError 对象

How to convert an exception into an NSError object

我想将异常消息转换为 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中说

You can convert an exception into an NSError object and then present the information in the error object to the user in an alert panel.

但是该指南没有显示代码示例,只显示了第二种方法的代码示例您也可以 return 在包含错误参数的方法中间接地使用它们 这对我想要的来说似乎很复杂。

那么,如何将异常转换为 NSError? The API reference of NSError 似乎没有合适的功能..

您无法将 NSException 转换为 NSError,因为 NSException 它们不具有相同的属性。有什么理由要抓住 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
}

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

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

header 文件说 NSUnderlyingErrorKey:

The value of this key should be an NSError.

但是 should 不是 must 并且盲目依赖于在字典中找到的东西具有特定 class 的代码是一开始就坏了。这也是 header;该密钥的官方开发人员文档没有说明这一点,该文档具有权威性。

对于那些想知道 e.userInfo ?: @{ }e.reason ?: @"???" 是什么意思的人来说,这只是一种更短的写作方式:

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

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