From fbb65d19884732f6191c06106340ab477cafc621 Mon Sep 17 00:00:00 2001 From: lilia Date: Tue, 22 Sep 2015 15:52:42 -0700 Subject: [PATCH] Add replayable network errors Support for manual message retry. // FREEBIE --- js/libtextsecure.js | 27 ++++++++++++++++++++++++++- js/models/messages.js | 8 ++++++++ libtextsecure/errors.js | 15 +++++++++++++++ libtextsecure/sendmessage.js | 12 +++++++++++- 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index d9b4cdc60..975373eac 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -9,6 +9,7 @@ var Type = { SEND_MESSAGE: 1, INIT_SESSION: 2, + NETWORK_REQUEST: 3, }; window.textsecure = window.textsecure || {}; window.textsecure.replay = { @@ -58,6 +59,20 @@ OutgoingIdentityKeyError.prototype = new ReplayableError(); OutgoingIdentityKeyError.prototype.constructor = OutgoingIdentityKeyError; + function NetworkError(number, jsonData, legacy, code) { + ReplayableError.call(this, { + functionCode : Type.NETWORK_REQUEST, + args : [number, jsonData, legacy] + }); + this.name = 'NetworkError'; + this.message = 'Network request failed' + this.code = code; + this.number = number; + } + NetworkError.prototype = new ReplayableError(); + NetworkError.prototype.constructor = NetworkError; + + window.textsecure.NetworkError = NetworkError; window.textsecure.IncomingIdentityKeyError = IncomingIdentityKeyError; window.textsecure.OutgoingIdentityKeyError = OutgoingIdentityKeyError; window.textsecure.ReplayableError = ReplayableError; @@ -39618,10 +39633,19 @@ MessageSender.prototype = { }); })).then(function(jsonData) { var legacy = (message instanceof textsecure.protobuf.DataMessage); - return this.server.sendMessages(number, jsonData, legacy); + return this.sendRequest(number, jsonData, legacy); }.bind(this)); }, + sendRequest: function(number, jsonData, legacy) { + return this.server.sendMessages(number, jsonData, legacy).catch(function(e) { + if (e.name === 'HTTPError' && e.code === -1) { + throw new NetworkError(number, jsonData, legacy); + } + throw e; + }); + }, + makeAttachmentPointer: function(attachment) { if (typeof attachment !== 'object' || attachment == null) { return Promise.resolve(undefined); @@ -40005,6 +40029,7 @@ window.textsecure = window.textsecure || {}; textsecure.MessageSender = function(url, username, password) { var sender = new MessageSender(url, username, password); textsecure.replay.registerFunction(sender.tryMessageAgain.bind(sender), textsecure.replay.Type.SEND_MESSAGE); + textsecure.replay.registerFunction(sender.sendRequest.bind(sender), textsecure.replay.Type.NETWORK_REQUEST); this.sendRequestGroupSyncMessage = sender.sendRequestGroupSyncMessage .bind(sender); this.sendRequestContactSyncMessage = sender.sendRequestContactSyncMessage.bind(sender); diff --git a/js/models/messages.js b/js/models/messages.js index dfcade19a..3da878b34 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -165,6 +165,14 @@ }); }, + resend: function(number) { + var error = this.getSendError(number); + if (error) { + var promise = new textsecure.ReplayableError(error).replay(); + this.send(promise); + } + }, + resolveConflict: function(number) { var error = this.getKeyConflict(number); if (error) { diff --git a/libtextsecure/errors.js b/libtextsecure/errors.js index c7a4fa0c9..d0eb5f3c3 100644 --- a/libtextsecure/errors.js +++ b/libtextsecure/errors.js @@ -8,6 +8,7 @@ var Type = { SEND_MESSAGE: 1, INIT_SESSION: 2, + NETWORK_REQUEST: 3, }; window.textsecure = window.textsecure || {}; window.textsecure.replay = { @@ -57,6 +58,20 @@ OutgoingIdentityKeyError.prototype = new ReplayableError(); OutgoingIdentityKeyError.prototype.constructor = OutgoingIdentityKeyError; + function NetworkError(number, jsonData, legacy, code) { + ReplayableError.call(this, { + functionCode : Type.NETWORK_REQUEST, + args : [number, jsonData, legacy] + }); + this.name = 'NetworkError'; + this.message = 'Network request failed' + this.code = code; + this.number = number; + } + NetworkError.prototype = new ReplayableError(); + NetworkError.prototype.constructor = NetworkError; + + window.textsecure.NetworkError = NetworkError; window.textsecure.IncomingIdentityKeyError = IncomingIdentityKeyError; window.textsecure.OutgoingIdentityKeyError = OutgoingIdentityKeyError; window.textsecure.ReplayableError = ReplayableError; diff --git a/libtextsecure/sendmessage.js b/libtextsecure/sendmessage.js index 8a7f6370f..56913181f 100644 --- a/libtextsecure/sendmessage.js +++ b/libtextsecure/sendmessage.js @@ -37,10 +37,19 @@ MessageSender.prototype = { }); })).then(function(jsonData) { var legacy = (message instanceof textsecure.protobuf.DataMessage); - return this.server.sendMessages(number, jsonData, legacy); + return this.sendRequest(number, jsonData, legacy); }.bind(this)); }, + sendRequest: function(number, jsonData, legacy) { + return this.server.sendMessages(number, jsonData, legacy).catch(function(e) { + if (e.name === 'HTTPError' && e.code === -1) { + throw new NetworkError(number, jsonData, legacy); + } + throw e; + }); + }, + makeAttachmentPointer: function(attachment) { if (typeof attachment !== 'object' || attachment == null) { return Promise.resolve(undefined); @@ -424,6 +433,7 @@ window.textsecure = window.textsecure || {}; textsecure.MessageSender = function(url, username, password) { var sender = new MessageSender(url, username, password); textsecure.replay.registerFunction(sender.tryMessageAgain.bind(sender), textsecure.replay.Type.SEND_MESSAGE); + textsecure.replay.registerFunction(sender.sendRequest.bind(sender), textsecure.replay.Type.NETWORK_REQUEST); this.sendRequestGroupSyncMessage = sender.sendRequestGroupSyncMessage .bind(sender); this.sendRequestContactSyncMessage = sender.sendRequestContactSyncMessage.bind(sender);