Skip to content

Commit

Permalink
Stop sticking an MTRErrorHolder in the userInfo of NSErrors.
Browse files Browse the repository at this point in the history
Otherwise the errors we create cannot be usefully encoded/decoded.

Fixes project-chip#22388
  • Loading branch information
bzbarsky-apple committed Feb 20, 2023
1 parent 0edb83a commit 07d196c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
7 changes: 5 additions & 2 deletions examples/darwin-framework-tool/commands/common/MTRError.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#import <inet/InetError.h>
#import <lib/support/TypeTraits.h>

#import <objc/runtime.h>

CHIP_ERROR MTRErrorToCHIPErrorCode(NSError * error)
{
if (error == nil) {
Expand All @@ -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) {
Expand Down
17 changes: 11 additions & 6 deletions src/darwin/Framework/CHIP/MTRError.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#import <inet/InetError.h>
#import <lib/support/TypeTraits.h>

#import <objc/runtime.h>

NSString * const MTRErrorDomain = @"MTRErrorDomain";

NSString * const MTRInteractionErrorDomain = @"MTRInteractionErrorDomain";
Expand All @@ -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];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 07d196c

Please sign in to comment.