diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 8c1e21f91..6751f3ec2 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -44,6 +44,8 @@ NSString *const kOWSProfileManager_GroupWhitelistCollection = @"kOWSProfileManag const NSUInteger kOWSProfileManager_NameDataLength = 26; const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; +typedef void (^ProfileManagerFailureBlock)(NSError *error); + @interface OWSProfileManager () @property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @@ -244,7 +246,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; successBlock(); }]; } - failure:^{ + failure:^(NSError *error) { failureBlock(); }]; }; @@ -275,11 +277,11 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; success:^(NSString *_Nullable avatarUrlPath) { tryToUpdateService(avatarUrlPath, fileName); } - failure:^{ + failure:^(NSError *error) { failureBlock(); }]; } - failure:^{ + failure:^(NSError *error) { failureBlock(); }]; } @@ -289,7 +291,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; success:^(NSString *_Nullable avatarUrlPath) { tryToUpdateService(nil, nil); } - failure:^{ + failure:^(NSError *error) { failureBlock(); }]; } else { @@ -300,8 +302,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; - (void)writeAvatarToDisk:(UIImage *)avatar success:(void (^)(NSData *data, NSString *fileName))successBlock - failure:(void (^)(void))failureBlock -{ + failure:(ProfileManagerFailureBlock)failureBlock { OWSAssertDebug(avatar); OWSAssertDebug(successBlock); OWSAssertDebug(failureBlock); @@ -316,12 +317,11 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; BOOL success = [data writeToFile:filePath atomically:YES]; OWSAssertDebug(success); if (success) { - successBlock(data, fileName); - return; + return successBlock(data, fileName); } } } - failureBlock(); + failureBlock(OWSErrorWithCodeDescription(OWSErrorCodeAvatarWriteFailed, @"Avatar write failed.")); }); } @@ -351,8 +351,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; // If avatarData is nil, we are clearing the avatar. - (void)uploadAvatarToService:(NSData *_Nullable)avatarData success:(void (^)(NSString *_Nullable avatarUrlPath))successBlock - failure:(void (^)(void))failureBlock -{ + failure:(ProfileManagerFailureBlock)failureBlock { OWSAssertDebug(successBlock); OWSAssertDebug(failureBlock); OWSAssertDebug(avatarData == nil || avatarData.length > 0); @@ -388,8 +387,8 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; if (![formResponseObject isKindOfClass:[NSDictionary class]]) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidResponse]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSDictionary *responseMap = formResponseObject; OWSLogError(@"responseObject: %@", formResponseObject); @@ -397,44 +396,44 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; NSString *formAcl = responseMap[@"acl"]; if (![formAcl isKindOfClass:[NSString class]] || formAcl.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAcl]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formKey = responseMap[@"key"]; if (![formKey isKindOfClass:[NSString class]] || formKey.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidKey]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formPolicy = responseMap[@"policy"]; if (![formPolicy isKindOfClass:[NSString class]] || formPolicy.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidPolicy]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formAlgorithm = responseMap[@"algorithm"]; if (![formAlgorithm isKindOfClass:[NSString class]] || formAlgorithm.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAlgorithm]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formCredential = responseMap[@"credential"]; if (![formCredential isKindOfClass:[NSString class]] || formCredential.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidCredential]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formDate = responseMap[@"date"]; if (![formDate isKindOfClass:[NSString class]] || formDate.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidDate]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } NSString *formSignature = responseMap[@"signature"]; if (![formSignature isKindOfClass:[NSString class]] || formSignature.length < 1) { OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidSignature]); - failureBlock(); - return; + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); } [self.avatarHTTPManager POST:@"" @@ -472,7 +471,8 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; } failure:^(NSURLSessionDataTask *_Nullable uploadTask, NSError *_Nonnull error) { OWSLogError(@"uploading avatar failed with error: %@", error); - failureBlock(); + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); }]; } failure:^(NSURLSessionDataTask *task, NSError *error) { @@ -483,15 +483,15 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; } OWSLogError(@"Failed to get profile avatar upload form: %@", error); - failureBlock(); + return failureBlock( + OWSErrorWithCodeDescription(OWSErrorCodeAvatarUploadFailed, @"Avatar upload failed.")); }]; }); } - (void)updateServiceWithProfileName:(nullable NSString *)localProfileName success:(void (^)(void))successBlock - failure:(void (^)(void))failureBlock -{ + failure:(ProfileManagerFailureBlock)failureBlock { OWSAssertDebug(successBlock); OWSAssertDebug(failureBlock); @@ -505,7 +505,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; } failure:^(NSURLSessionDataTask *task, NSError *error) { OWSLogError(@"Failed to update profile with error: %@", error); - failureBlock(); + failureBlock(error); }]; }); } @@ -566,11 +566,12 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; [self rotateLocalProfileKeyIfNecessaryWithSuccess:^{ } - failure:^ { + failure:^(NSError *error) { }]; } -- (void)rotateLocalProfileKeyIfNecessaryWithSuccess:(dispatch_block_t)success failure:(dispatch_block_t)failure { +- (void)rotateLocalProfileKeyIfNecessaryWithSuccess:(dispatch_block_t)success + failure:(ProfileManagerFailureBlock)failure { OWSAssertDebug(AppReadiness.isAppReady); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -620,7 +621,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; BOOL isProfileKeySharedWithBlocked = (intersectingRecipientIds.count > 0 || intersectingGroupIds.count > 0); if (!isProfileKeySharedWithBlocked) { // No need to rotate the profile key. - return; + return success(); } // Rotate the profile key @@ -656,9 +657,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; // The value doesn't matter, we just need any non-NSError value. resolve(@(1)); } - failure:^{ - NSError *error = OWSErrorWithCodeDescription( - OWSErrorCodeProfileUpdateFailed, @"Update to profile name failed."); + failure:^(NSError *error) { resolve(error); }]; }]; @@ -686,10 +685,8 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; resolve(@(1)); }]; } - failure:^{ + failure:^(NSError *error) { OWSLogInfo(@"Update to profile avatar after profile key rotation failed."); - NSError *error = OWSErrorWithCodeDescription( - OWSErrorCodeProfileUpdateFailed, @"Update to profile avatar failed."); resolve(error); }]; }]; @@ -717,8 +714,12 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; promise = promise.then(^(id value) { success(); }); - promise = promise.catch(^(id error) { - failure(); + promise = promise.catch(^(NSError *error) { + if ([error isKindOfClass:[NSError class]]) { + failure(error); + } else { + failure(OWSErrorWithCodeDescription(OWSErrorCodeProfileUpdateFailed, @"Profile key rotation failed.")); + } }); [promise retainUntilComplete]; }); diff --git a/SignalServiceKit/src/Util/OWSError.h b/SignalServiceKit/src/Util/OWSError.h index 831f2060b..238ab6b6d 100644 --- a/SignalServiceKit/src/Util/OWSError.h +++ b/SignalServiceKit/src/Util/OWSError.h @@ -49,6 +49,8 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) { OWSErrorCodeMessageResponseFailed = 777422, OWSErrorCodeInvalidMessage = 777423, OWSErrorCodeProfileUpdateFailed = 777424, + OWSErrorCodeAvatarWriteFailed = 777425, + OWSErrorCodeAvatarUploadFailed = 777426, }; extern NSString *const OWSErrorRecipientIdentifierKey;