From 07d196c54fd25f3457d0c77eb7eefe41db8281ef Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Sat, 18 Feb 2023 01:01:22 -0500 Subject: [PATCH] Stop sticking an MTRErrorHolder in the userInfo of NSErrors. Otherwise the errors we create cannot be usefully encoded/decoded. Fixes https://github.com/project-chip/connectedhomeip/issues/22388 --- .../commands/common/MTRError.mm | 7 +++++-- src/darwin/Framework/CHIP/MTRError.mm | 17 +++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/examples/darwin-framework-tool/commands/common/MTRError.mm b/examples/darwin-framework-tool/commands/common/MTRError.mm index c393682a7a84e0..5d348c83c7fdf3 100644 --- a/examples/darwin-framework-tool/commands/common/MTRError.mm +++ b/examples/darwin-framework-tool/commands/common/MTRError.mm @@ -25,6 +25,8 @@ #import #import +#import + CHIP_ERROR MTRErrorToCHIPErrorCode(NSError * error) { if (error == nil) { @@ -43,8 +45,9 @@ CHIP_ERROR MTRErrorToCHIPErrorCode(NSError * error) return CHIP_ERROR_INTERNAL; } - if (error.userInfo != nil) { - id underlyingError = error.userInfo[@"underlyingError"]; + { + void * key = (__bridge void *) NSClassFromString(@"MTRErrorHolder"); + id underlyingError = objc_getAssociatedObject(error, key); if (underlyingError != nil) { NSValue * chipErrorValue = [underlyingError valueForKey:@"error"]; if (chipErrorValue != nil) { diff --git a/src/darwin/Framework/CHIP/MTRError.mm b/src/darwin/Framework/CHIP/MTRError.mm index 00bd61d30bb995..4f907145ce5dcf 100644 --- a/src/darwin/Framework/CHIP/MTRError.mm +++ b/src/darwin/Framework/CHIP/MTRError.mm @@ -24,6 +24,8 @@ #import #import +#import + NSString * const MTRErrorDomain = @"MTRErrorDomain"; NSString * const MTRInteractionErrorDomain = @"MTRInteractionErrorDomain"; @@ -47,6 +49,8 @@ + (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode return nil; } + ChipLogError(Controller, "Creating NSError from %" CHIP_ERROR_FORMAT, errorCode.Format()); + if (errorCode.IsIMStatus()) { chip::app::StatusIB status(errorCode); return [MTRError errorForIMStatus:status]; @@ -94,10 +98,10 @@ + (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode }]; } - userInfo[@"underlyingError"] = [[MTRErrorHolder alloc] initWithError:errorCode]; - - return [NSError errorWithDomain:MTRErrorDomain code:code userInfo:userInfo]; - ; + auto * error = [NSError errorWithDomain:MTRErrorDomain code:code userInfo:userInfo]; + void * key = (__bridge void *) [MTRErrorHolder class]; + objc_setAssociatedObject(error, key, [[MTRErrorHolder alloc] initWithError:errorCode], OBJC_ASSOCIATION_RETAIN_NONATOMIC); + return error; } + (NSError *)errorForIMStatus:(const chip::app::StatusIB &)status @@ -237,8 +241,9 @@ + (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error return CHIP_ERROR_INTERNAL; } - if (error.userInfo != nil) { - id underlyingError = error.userInfo[@"underlyingError"]; + { + void * key = (__bridge void *) [MTRErrorHolder class]; + id underlyingError = objc_getAssociatedObject(error, key); if (underlyingError != nil && [underlyingError isKindOfClass:[MTRErrorHolder class]]) { return ((MTRErrorHolder *) underlyingError).error; }