Fix message sending error handling

pull/26/head
Niels Andriesse 5 years ago
parent f83fdcbf70
commit 1fafa550f0

@ -320,7 +320,7 @@ static NSTimeInterval launchStartedAt;
if (self.lokiP2PServer.isRunning) { break; }
BOOL isStarted = [self.lokiP2PServer startOnPort:port.unsignedIntegerValue];
if (isStarted) {
OWSLogInfo(@"[Loki] Started server at %@.", self.lokiP2PServer.serverURL);
OWSLogInfo(@"[Loki] Started server at \"%@\".", self.lokiP2PServer.serverURL);
break;
}
}

@ -767,6 +767,7 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
- (void)saveFriendRequestStatus:(TSThreadFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction
{
OWSLogInfo(@"[Loki] Setting thread friend request status to %d.", friendRequestStatus);
self.friendRequestStatus = friendRequestStatus;
void (^postNotification)() = ^() {
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.threadFriendRequestStatusChanged object:self.uniqueId];

@ -35,6 +35,18 @@ internal extension LokiAPI {
}
}
internal extension Promise {
internal func recoveringNetworkErrorsIfNeeded() -> Promise<T> {
return recover() { error -> Promise<T> in
switch error {
case NetworkManagerError.taskError(_, let underlyingError): throw underlyingError
default: throw error
}
}
}
}
internal extension AnyPromise {
internal static func from<T : Any>(_ promise: Promise<T>) -> AnyPromise {

@ -31,7 +31,7 @@ public extension LokiAPI {
// MARK: Internal API
private static func getRandomSnode() -> Promise<Target> {
return Promise<Target> { seal in
seal.fulfill(Target(address: "http://13.236.173.190", port: 8080)) // TODO: For debugging purposes
seal.fulfill(Target(address: "http://13.236.173.191", port: 8080)) // TODO: For debugging purposes
}
}
@ -53,7 +53,7 @@ public extension LokiAPI {
private static func parseTargets(from rawResponse: Any) -> [Target] {
// TODO: For debugging purposes
// ========
let target = Target(address: "http://13.236.173.190", port: defaultSnodePort)
let target = Target(address: "http://13.236.173.191", port: defaultSnodePort)
return Array(repeating: target, count: 3)
// ========
// guard let json = rawResponse as? JSON, let addresses = json["snodes"] as? [String] else {
@ -76,6 +76,7 @@ internal extension Promise {
Logger.warn("[Loki] There appears to be a problem with LokiNet.")
case 421:
// The snode isn't associated with the given public key anymore
Logger.warn("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).")
let swarm = LokiAPI.swarmCache[hexEncodedPublicKey]
if var swarm = swarm, let index = swarm.firstIndex(of: target) {
swarm.remove(at: index)

@ -28,7 +28,8 @@ import PromiseKit
internal static func invoke(_ method: Target.Method, on target: Target, associatedWith hexEncodedPublicKey: String, parameters: [String:Any] = [:]) -> Promise<RawResponse> {
let url = URL(string: "\(target.address):\(target.port)/\(version)/storage_rpc")!
let request = TSRequest(url: url, method: "POST", parameters: [ "method" : method.rawValue, "params" : parameters ])
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey)
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }
.handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey).recoveringNetworkErrorsIfNeeded()
}
// MARK: Public API

@ -443,6 +443,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
- (void)saveFriendRequestStatus:(TSMessageFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction
{
OWSLogInfo(@"[Loki] Setting message friend request status to %d.", friendRequestStatus);
self.friendRequestStatus = friendRequestStatus;
void (^postNotification)() = ^() {
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.messageFriendRequestStatusChanged object:self.uniqueId];

@ -21,7 +21,7 @@ public class OWSMessageSend: NSObject {
@objc
public let recipient: SignalRecipient
private static let kMaxRetriesPerRecipient: Int = 3
private static let kMaxRetriesPerRecipient: Int = 1
@objc
public var remainingAttempts = OWSMessageSend.kMaxRetriesPerRecipient

@ -1066,10 +1066,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
hasValidMessageType = [validMessageTypes containsObject:messageType];
/* Loki: Original code
hasValidMessageType = ([messageType isEqualToNumber:@(TSEncryptedWhisperMessageType)] ||
[messageType isEqualToNumber:@(TSPreKeyWhisperMessageType)]);
* ========
hasValidMessageType = ([messageType isEqualToNumber:@(TSEncryptedWhisperMessageType)] || [messageType isEqualToNumber:@(TSPreKeyWhisperMessageType)]);
* ========
*/
}
if (!hasValidMessageType) {
@ -1103,16 +1103,45 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return messageSend.failure(error);
}
// Update the state to show that the proof of work is being calculated
[self saveIsCalculatingProofOfWork:YES forMessage:messageSend];
// Convert the message to a Loki message and send it using the Loki messaging API
// Get the message parameters and type
NSDictionary *signalMessage = deviceMessages.firstObject;
// Update the message and thread if needed
NSInteger *messageType = ((NSNumber *)signalMessage[@"type"]).integerValue;
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:nil];
[message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:nil];
}
TSWhisperMessageType messageType = ((NSNumber *)signalMessage[@"type"]).integerValue;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
// Update the PoW calculation status
[message saveIsCalculatingProofOfWork:YES withTransaction:transaction];
// Update the message and thread if needed
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:transaction];
[message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:transaction];
}
}];
// Convenience
void (^handleError)(NSError *error) = ^(NSError *error) {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
// Update the thread if needed
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:transaction];
}
// Update the PoW calculation status
[message saveIsCalculatingProofOfWork:NO withTransaction:transaction];
}];
// Handle the error
NSUInteger statusCode = 0;
NSData *_Nullable responseData = nil;
if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) {
statusCode = error.code;
NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey];
if (underlyingError) {
responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
} else {
OWSFailDebug(@"Missing underlying error: %@.", error);
}
} else {
OWSFailDebug(@"Unexpected error: %@.", error);
}
[self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData];
};
// Convert the message to a Loki message and send it using the Loki API
[[LokiAPI objc_sendSignalMessage:signalMessage to:recipient.recipientId with:message.timestamp]
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
NSSet<AnyPromise *> *promises = (NSSet<AnyPromise *> *)result;
@ -1140,29 +1169,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) {
errorCount += 1;
if (errorCount != promiseCount) { return; } // Only error out if all promises failed
// Update the thread if needed
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:nil];
}
// Update the PoW calculation status
[self saveIsCalculatingProofOfWork:NO forMessage:messageSend];
// Handle the error
NSUInteger statusCode = 0;
NSData *_Nullable responseData = nil;
if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) {
statusCode = error.code;
NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey];
if (underlyingError) {
responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
} else {
OWSFailDebug(@"Missing underlying error: %@.", error);
}
} else {
OWSFailDebug(@"Unexpected error: %@.", error);
}
[self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData];
handleError(error);
}) retainUntilComplete];
}
})
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // Unreachable snode; usually a problem with LokiNet
handleError(error);
}) retainUntilComplete];
// Loki: Original code

@ -81,7 +81,7 @@ public class MessageSenderJobQueue: NSObject, JobQueue {
public typealias DurableOperationType = MessageSenderOperation
public static let jobRecordLabel: String = "MessageSender"
public static let maxRetries: UInt = 30
public static let maxRetries: UInt = 1
public let requiresInternet: Bool = true
public var runningOperations: [MessageSenderOperation] = []

Loading…
Cancel
Save