Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve round-tripping of CHIP_ERROR through NSError. #17194

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 75 additions & 51 deletions src/darwin/Framework/CHIP/CHIPError.mm
Original file line number Diff line number Diff line change
Expand Up @@ -41,55 +41,51 @@ + (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode
return [CHIPError errorForIMStatus:status];
}

if (errorCode == CHIP_ERROR_INVALID_STRING_LENGTH) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeInvalidStringLength
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"A list length is invalid.", nil) }];
}

if (errorCode == CHIP_ERROR_INVALID_INTEGER_VALUE) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeInvalidIntegerValue
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Unexpected integer value.", nil) }];
}

if (errorCode == CHIP_ERROR_INVALID_ARGUMENT) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeInvalidArgument
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"An argument is invalid.", nil) }];
}

if (errorCode == CHIP_ERROR_INVALID_MESSAGE_LENGTH) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeInvalidMessageLength
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"A message length is invalid.", nil) }];
}
NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] init];
CHIPErrorCode code = CHIPErrorCodeGeneralError;

if (errorCode == CHIP_ERROR_INCORRECT_STATE) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeInvalidState
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Invalid object state.", nil) }];
if (errorCode == CHIP_ERROR_INVALID_STRING_LENGTH) {
code = CHIPErrorCodeInvalidStringLength;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"A list length is invalid.", nil) }];
} else if (errorCode == CHIP_ERROR_INVALID_INTEGER_VALUE) {
code = CHIPErrorCodeInvalidIntegerValue;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Unexpected integer value.", nil) }];
} else if (errorCode == CHIP_ERROR_INVALID_ARGUMENT) {
code = CHIPErrorCodeInvalidArgument;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"An argument is invalid.", nil) }];
} else if (errorCode == CHIP_ERROR_INVALID_MESSAGE_LENGTH) {
code = CHIPErrorCodeInvalidMessageLength;
[userInfo
addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"A message length is invalid.", nil) }];
} else if (errorCode == CHIP_ERROR_INCORRECT_STATE) {
code = CHIPErrorCodeInvalidState;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Invalid object state.", nil) }];
} else if (errorCode == CHIP_ERROR_INTEGRITY_CHECK_FAILED) {
code = CHIPErrorCodeIntegrityCheckFailed;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Integrity check failed.", nil) }];
} else if (errorCode == CHIP_ERROR_TIMEOUT) {
code = CHIPErrorCodeTimeout;
[userInfo addEntriesFromDictionary:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Transaction timed out.", nil) }];
} else {
code = CHIPErrorCodeGeneralError;
[userInfo addEntriesFromDictionary:@{
NSLocalizedDescriptionKey :
[NSString stringWithFormat:NSLocalizedString(@"Undefined error:%u.", nil), errorCode.AsInteger()],
@"errorCode" : @(errorCode.AsInteger()),
}];
}

if (errorCode == CHIP_ERROR_INTEGRITY_CHECK_FAILED) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeIntegrityCheckFailed
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Integrity check failed.", nil) }];
#if CHIP_CONFIG_ERROR_SOURCE
if (errorCode.GetFile()) {
userInfo[@"errorFile"] = [NSString stringWithUTF8String:errorCode.GetFile()];
}

if (errorCode == CHIP_ERROR_TIMEOUT) {
return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeTimeout
userInfo:@{ NSLocalizedDescriptionKey : NSLocalizedString(@"Transaction timed out.", nil) }];
if (errorCode.GetLine()) {
userInfo[@"errorLine"] = @(errorCode.GetLine());
}
#endif // CHIP_CONFIG_ERROR_SOURCE

return [NSError errorWithDomain:CHIPErrorDomain
code:CHIPErrorCodeGeneralError
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:NSLocalizedString(@"Undefined error:%u.", nil), errorCode.AsInteger()],
@"errorCode" : @(errorCode.AsInteger()),
}];
return [NSError errorWithDomain:CHIPErrorDomain code:code userInfo:userInfo];
;
}

Expand Down Expand Up @@ -220,7 +216,7 @@ + (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error

if (error.domain == MatterInteractionErrorDomain) {
chip::app::StatusIB status(static_cast<chip::Protocols::InteractionModel::Status>(error.code));
if (error.userInfo[@"clusterStatus"] != nil) {
if (error.userInfo != nil && error.userInfo[@"clusterStatus"] != nil) {
status.mClusterStatus.Emplace([error.userInfo[@"clusterStatus"] unsignedCharValue]);
}
return status.ToChipError();
Expand All @@ -230,24 +226,52 @@ + (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error
return CHIP_ERROR_INTERNAL;
}

chip::ChipError::StorageType code;
switch (error.code) {
case CHIPErrorCodeInvalidStringLength:
return CHIP_ERROR_INVALID_STRING_LENGTH;
code = CHIP_ERROR_INVALID_STRING_LENGTH.AsInteger();
break;
case CHIPErrorCodeInvalidIntegerValue:
return CHIP_ERROR_INVALID_INTEGER_VALUE;
code = CHIP_ERROR_INVALID_INTEGER_VALUE.AsInteger();
break;
case CHIPErrorCodeInvalidArgument:
return CHIP_ERROR_INVALID_ARGUMENT;
code = CHIP_ERROR_INVALID_ARGUMENT.AsInteger();
break;
case CHIPErrorCodeInvalidMessageLength:
return CHIP_ERROR_INVALID_MESSAGE_LENGTH;
code = CHIP_ERROR_INVALID_MESSAGE_LENGTH.AsInteger();
break;
case CHIPErrorCodeInvalidState:
return CHIP_ERROR_INCORRECT_STATE;
code = CHIP_ERROR_INCORRECT_STATE.AsInteger();
break;
case CHIPErrorCodeIntegrityCheckFailed:
return CHIP_ERROR_INTEGRITY_CHECK_FAILED;
code = CHIP_ERROR_INTEGRITY_CHECK_FAILED.AsInteger();
break;
case CHIPErrorCodeTimeout:
return CHIP_ERROR_TIMEOUT;
code = CHIP_ERROR_TIMEOUT.AsInteger();
break;
case CHIPErrorCodeGeneralError: {
if (error.userInfo != nil && error.userInfo[@"errorCode"] != nil) {
code = static_cast<decltype(code)>([error.userInfo[@"errorCode"] unsignedLongValue]);
break;
}
// Weird error we did not create. Fall through.
default:
return CHIP_ERROR_INTERNAL;
code = CHIP_ERROR_INTERNAL.AsInteger();
break;
}
}

const char * file = nullptr;
unsigned int line = 0;
if (error.userInfo != nil) {
if (error.userInfo[@"errorFile"] != nil) {
file = [error.userInfo[@"errorFile"] cStringUsingEncoding:NSUTF8StringEncoding];
}
if (error.userInfo[@"errorLine"] != nil) {
line = [error.userInfo[@"errorLine"] unsignedIntValue];
}
}
return chip::ChipError(code, file, line);
}

@end