Instrument errors in message sender.

// FREEBIE
pull/1/head
Matthew Chen 9 years ago
parent e168db79aa
commit 19c0a7ad7c

@ -186,7 +186,7 @@ NSUInteger const OWSSendMessageOperationMaxRetries = 4;
_successHandler = ^{ _successHandler = ^{
typeof(self) strongSelf = weakSelf; typeof(self) strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
OWSCAssert(NO); OWSProdCFail(@"message_sender_error_send_operation_did_not_complete");
return; return;
} }
@ -200,7 +200,7 @@ NSUInteger const OWSSendMessageOperationMaxRetries = 4;
_failureHandler = ^(NSError *_Nonnull error) { _failureHandler = ^(NSError *_Nonnull error) {
typeof(self) strongSelf = weakSelf; typeof(self) strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
OWSCAssert(NO); OWSProdCFail(@"message_sender_error_send_operation_did_not_complete");
return; return;
} }
@ -474,7 +474,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[TSAttachmentStream fetchObjectWithUniqueID:message.attachmentIds.firstObject]; [TSAttachmentStream fetchObjectWithUniqueID:message.attachmentIds.firstObject];
if (!attachmentStream) { if (!attachmentStream) {
DDLogError(@"%@ Unable to find local saved attachment to upload.", self.tag); OWSProdError(@"message_sender_error_could_not_load_attachment");
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError(); NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
// Not finding local attachment is a terminal failure. // Not finding local attachment is a terminal failure.
[error setIsRetryable:NO]; [error setIsRetryable:NO];
@ -539,7 +539,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSError *error; NSError *error;
[attachmentStream writeData:dataCopy error:&error]; [attachmentStream writeData:dataCopy error:&error];
if (error) { if (error) {
DDLogError(@"%@ Failed to write data for outgoing attachment with error:%@", self.tag, error); OWSProdErrorWNSError(@"message_sender_error_could_not_write_attachment", error);
return failureHandler(error); return failureHandler(error);
} }
@ -575,7 +575,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (recipients.count == 0 && !*error) { if (recipients.count == 0 && !*error) {
// error should be set in contactsUpater, but just in case. // error should be set in contactsUpater, but just in case.
DDLogError(@"%@ Unknown error finding contacts", self.tag); OWSProdError(@"message_sender_error_could_not_find_contacts_1");
*error = OWSErrorMakeFailedToSendOutgoingMessageError(); *error = OWSErrorMakeFailedToSendOutgoingMessageError();
} }
@ -598,7 +598,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (recipients.count == 0) { if (recipients.count == 0) {
if (!error) { if (!error) {
DDLogError(@"%@ Unknown error finding contacts", self.tag); OWSProdError(@"message_sender_error_could_not_find_contacts_2");
error = OWSErrorMakeFailedToSendOutgoingMessageError(); error = OWSErrorMakeFailedToSendOutgoingMessageError();
} }
// If no recipients were found, there's no reason to retry. It will just fail again. // If no recipients were found, there's no reason to retry. It will just fail again.
@ -652,7 +652,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self unregisteredRecipient:recipient message:message thread:thread]; [self unregisteredRecipient:recipient message:message thread:thread];
} }
DDLogError(@"%@ contact lookup failed with error: %@", self.tag, error); OWSProdErrorWNSError(@"message_sender_error_could_not_find_contacts_3", error);
// No need to repeat trying to find a failure. Apart from repeatedly failing, it would also cause us // No need to repeat trying to find a failure. Apart from repeatedly failing, it would also cause us
// to print redundant error messages. // to print redundant error messages.
[error setIsRetryable:NO]; [error setIsRetryable:NO];
@ -678,10 +678,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
success:successHandler success:successHandler
failure:failureHandler]; failure:failureHandler];
} else { } else {
DDLogError(@"%@ Unexpected unhandlable message: %@", self.tag, message);
// Neither a group nor contact thread? This should never happen. // Neither a group nor contact thread? This should never happen.
OWSAssert(NO); OWSFail(@"%@ Unknown message type: %@", self.tag, NSStringFromClass([message class]));
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError(); NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
[error setIsRetryable:NO]; [error setIsRetryable:NO];
@ -851,7 +849,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
DDLogWarn(@"%@ Failed to update prekeys with the server: %@", self.tag, error); DDLogWarn(@"%@ Failed to update prekeys with the server: %@", self.tag, error);
}]; }];
DDLogError(@"%@ Message send failed due to repeated inability to update prekeys.", self.tag);
NSError *error = OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError(); NSError *error = OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError();
[error setIsRetryable:YES]; [error setIsRetryable:YES];
return failureHandler(error); return failureHandler(error);
@ -859,8 +856,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (remainingAttempts <= 0) { if (remainingAttempts <= 0) {
// We should always fail with a specific error. // We should always fail with a specific error.
DDLogError(@"%@ Unexpected generic failure.", self.tag); OWSProdFail(@"message_sender_error_generic_send_failure");
OWSAssert(NO);
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError(); NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
[error setIsRetryable:YES]; [error setIsRetryable:YES];
@ -897,7 +893,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
PreKeyBundle *newKeyBundle = exception.userInfo[TSInvalidPreKeyBundleKey]; PreKeyBundle *newKeyBundle = exception.userInfo[TSInvalidPreKeyBundleKey];
if (![newKeyBundle isKindOfClass:[PreKeyBundle class]]) { if (![newKeyBundle isKindOfClass:[PreKeyBundle class]]) {
OWSFail(@"%@ unexpected TSInvalidPreKeyBundleKey: %@", self.tag, newKeyBundle); OWSProdFail(@"message_sender_error_unexpected_key_bundle");
failureHandler(error); failureHandler(error);
return; return;
} }
@ -905,14 +901,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSData *newIdentityKeyWithVersion = newKeyBundle.identityKey; NSData *newIdentityKeyWithVersion = newKeyBundle.identityKey;
if (![newIdentityKeyWithVersion isKindOfClass:[NSData class]]) { if (![newIdentityKeyWithVersion isKindOfClass:[NSData class]]) {
OWSFail(@"%@ unexpected TSInvalidRecipientKey: %@", self.tag, newIdentityKeyWithVersion); OWSProdFail(@"message_sender_error_invalid_identity_key_type");
failureHandler(error); failureHandler(error);
return; return;
} }
// TODO migrate to storing the full 33 byte representation of the identity key. // TODO migrate to storing the full 33 byte representation of the identity key.
if (newIdentityKeyWithVersion.length != kIdentityKeyLength) { if (newIdentityKeyWithVersion.length != kIdentityKeyLength) {
OWSFail(@"%@ unexpected key length: %lu", self.tag, (unsigned long)newIdentityKeyWithVersion.length); OWSProdFail(@"message_sender_error_invalid_identity_key_length");
failureHandler(error); failureHandler(error);
return; return;
} }
@ -1017,7 +1013,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSDictionary *serializedResponse = NSDictionary *serializedResponse =
[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error]; [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
if (error) { if (error) {
DDLogError(@"%@ Failed to serialize response of mismatched devices: %@", self.tag, error); OWSProdErrorWNSError(@"message_sender_error_could_not_parse_mismatched_devices_json", error);
[error setIsRetryable:YES]; [error setIsRetryable:YES];
return failureHandler(error); return failureHandler(error);
} }
@ -1057,8 +1053,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
dispatch_async([OWSDispatch sessionStoreQueue], ^{ dispatch_async([OWSDispatch sessionStoreQueue], ^{
if (extraDevices.count < 1 && missingDevices.count < 1) { if (extraDevices.count < 1 && missingDevices.count < 1) {
DDLogError(@"%@ No missing or extra devices in %s", self.tag, __PRETTY_FUNCTION__); OWSProdFail(@"message_sender_error_no_missing_or_extra_devices");
OWSAssert(NO);
} }
if (extraDevices && extraDevices.count > 0) { if (extraDevices && extraDevices.count > 0) {
@ -1221,7 +1216,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
dispatch_semaphore_signal(sema); dispatch_semaphore_signal(sema);
} }
failure:^(NSURLSessionDataTask *task, NSError *error) { failure:^(NSURLSessionDataTask *task, NSError *error) {
DDLogError(@"Server replied on PreKeyBundle request with error: %@", error); DDLogError(@"Server replied to PreKeyBundle request with error: %@", error);
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
if (response.statusCode == 404) { if (response.statusCode == 404) {
// Can't throw exception from within callback as it's probabably a different thread. // Can't throw exception from within callback as it's probabably a different thread.
@ -1292,7 +1287,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
if (error) { if (error) {
DDLogError(@"Error while making JSON dictionary of message: %@", error.debugDescription); OWSProdErrorWNSError(@"message_send_error_could_not_serialize_message_json", error);
return nil; return nil;
} }

@ -57,7 +57,14 @@ NS_ASSUME_NONNULL_BEGIN
} }
#define OWSProdErrorWEnvelope(__analyticsEventName, __envelope) \ #define OWSProdErrorWEnvelope(__analyticsEventName, __envelope) \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromEnvelope(__envelope)) { \
DDLogError(@"%s:%d %@: %@", \
__PRETTY_FUNCTION__, \
__LINE__, \
__analyticsEventName, \
[self descriptionForEnvelope:__envelope]); \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromEnvelope(__envelope)) \
}
@interface TSMessagesManager () @interface TSMessagesManager ()

@ -353,7 +353,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
BOOL shouldHavePassword = [NSFileManager.defaultManager fileExistsAtPath:[self dbPath]]; BOOL shouldHavePassword = [NSFileManager.defaultManager fileExistsAtPath:[self dbPath]];
if (shouldHavePassword) { if (shouldHavePassword) {
OWSProdErrorWNSError(@"storage_error_could_not_load_database_second_attempt", keyFetchError); OWSProdError(@"storage_error_could_not_load_database_second_attempt");
} }
// Try to reset app by deleting database. // Try to reset app by deleting database.

@ -67,8 +67,7 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
// //
// parametersBlock is of type OWSProdAssertParametersBlock. // parametersBlock is of type OWSProdAssertParametersBlock.
// The "C" variants (e.g. OWSProdAssert() vs. OWSProdCAssert() should be used in free functions, // The "C" variants (e.g. OWSProdAssert() vs. OWSProdCAssert() should be used in free functions,
// where there is no self. // where there is no self. They can also be used in blocks to avoid capturing a reference to self.
//
#define OWSProdAssertWParamsTemplate(__value, __analyticsEventName, __parametersBlock, __assertMacro) \ #define OWSProdAssertWParamsTemplate(__value, __analyticsEventName, __parametersBlock, __assertMacro) \
{ \ { \
if (!(BOOL)(__value)) { \ if (!(BOOL)(__value)) { \
@ -134,10 +133,16 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
} }
#define OWSProdFailWNSError(__analyticsEventName, __nserror) \ #define OWSProdFailWNSError(__analyticsEventName, __nserror) \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) { \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, error.debugDescription); \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) \
}
#define OWSProdFailWNSException(__analyticsEventName, __exception) \ #define OWSProdFailWNSException(__analyticsEventName, __exception) \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) { \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __exception); \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) \
}
#define OWSProdEventWParams(__severityLevel, __analyticsEventName, __parametersBlock) \ #define OWSProdEventWParams(__severityLevel, __analyticsEventName, __parametersBlock) \
{ \ { \
@ -163,9 +168,15 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
#define OWSProdCFail(__analyticsEventName) OWSProdCFailWParams(__analyticsEventName, nil) #define OWSProdCFail(__analyticsEventName) OWSProdCFailWParams(__analyticsEventName, nil)
#define OWSProdErrorWNSError(__analyticsEventName, __nserror) \ #define OWSProdErrorWNSError(__analyticsEventName, __nserror) \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) { \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, error.debugDescription); \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) \
}
#define OWSProdErrorWNSException(__analyticsEventName, __exception) \ #define OWSProdErrorWNSException(__analyticsEventName, __exception) \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) { \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __exception); \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) \
}
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save