diff --git a/js/api.js b/js/api.js index 39d57c86c..629a2523f 100644 --- a/js/api.js +++ b/js/api.js @@ -85,31 +85,27 @@ window.textsecure.api = function() { } if (code > 999 || code < 100) code = -1; - var e = new Error(code); - e.name = "HTTPError"; - switch (code) { - case -1: - e.human_error = "Failed to connect to the server, please check your network connection."; - break; - case 413: - e.human_error = "Rate limit exceeded, please try again later."; - break; - case 403: - e.human_error = "Invalid code, please try again."; - break; - case 417: - e.human_error = "Number already registered"; // TODO: This shouldn't be a thing?, but its in the API doc? - break; - case 401: - e.human_error = "Invalid authentication, most likely someone re-registered and invalidated our registration"; - break; - case 404: - e.human_error = "Number is not registered with TextSecure.."; - break; - default: - e.human_error = "The server rejected our query, please file a bug report."; + try { + switch (code) { + case -1: + textsecure.throwHumanError(code, "HTTPError", "Failed to connect to the server, please check your network connection."); + case 413: + textsecure.throwHumanError(code, "HTTPError", "Rate limit exceeded, please try again later."); + case 403: + textsecure.throwHumanError(code, "HTTPError", "Invalid code, please try again."); + case 417: + // TODO: This shouldn't be a thing?, but its in the API doc? + textsecure.throwHumanError(code, "HTTPError", "Number already registered."); + case 401: + textsecure.throwHumanError(code, "HTTPError", "Invalid authentication, most likely someone re-registered and invalidated our registration."); + case 404: + textsecure.throwHumanError(code, "HTTPError", "Number is not registered with TextSecure."); + default: + textsecure.throwHumanError(code, "HTTPError", "The server rejected our query, please file a bug report."); + } + } catch (e) { + reject(e); } - reject(e); } }); }); diff --git a/js/crypto.js b/js/crypto.js index c6aaeccc4..d2b7777dd 100644 --- a/js/crypto.js +++ b/js/crypto.js @@ -417,10 +417,7 @@ window.textsecure.crypto = new function() { } else { // ...otherwise create an error that the UI will pick up and ask the user if they want to re-negotiate // TODO: Save the message for possible later renegotiation - var error = new Error("Received message with unknown identity key"); - error.name = "WarnTryAgainError"; - error.full_message = "The identity of the sender has changed. This may be malicious, or the sender may have simply reinstalled TextSecure."; - throw new error; + textsecure.throwHumanError("Received message with unknown identity key", "WarnTryAgainError", "The identity of the sender has changed. This may be malicious, or the sender may have simply reinstalled TextSecure."); } } return initSession(false, preKeyPair, encodedNumber, toArrayBuffer(message.identityKey), toArrayBuffer(message.baseKey)) diff --git a/js/helpers.js b/js/helpers.js index 45107990b..9c56ad34e 100644 --- a/js/helpers.js +++ b/js/helpers.js @@ -277,6 +277,14 @@ window.textsecure.utils = function() { return self; }(); +window.textsecure.throwHumanError = function(error, type, humanError) { + var e = new Error(error); + if (type !== undefined) + e.name = type; + e.humanError = humanError; + throw e; +} + /************************************************ *** Utilities to store data in local storage *** ************************************************/ @@ -500,6 +508,7 @@ window.textsecure.subscribeToPush = function() { }); }) }).catch(function(e) { + // TODO: Show "Invalid message" messages? console.log("Error handling incoming message: "); console.log(e); }); @@ -533,20 +542,11 @@ window.textsecure.sendMessage = function() { var promises = []; var addEncryptionFor = function(i) { - return textsecure.crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) { - jsonData[i] = { - type: encryptedMsg.type, - destination: deviceObjectList[i].encodedNumber, - destinationRegistrationId: deviceObjectList[i].registrationId, - body: encryptedMsg.body, - timestamp: new Date().getTime() - }; - + return new Promise(function(resolve) { // Wrap in a promise for the throws if (deviceObjectList[i].relay !== undefined) { - jsonData[i].relay = deviceObjectList[i].relay; if (relay === undefined) - relay = jsonData[i].relay; - else if (relay != jsonData[i].relay) + relay = deviceObjectList[i].relay; + else if (relay != deviceObjectList[i].relay) throw new Error("Mismatched relays for number " + number); } else { if (relay === undefined) @@ -554,8 +554,22 @@ window.textsecure.sendMessage = function() { else if (relay != "") throw new Error("Mismatched relays for number " + number); } + + return textsecure.crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) { + jsonData[i] = { + type: encryptedMsg.type, + destination: deviceObjectList[i].encodedNumber, + destinationRegistrationId: deviceObjectList[i].registrationId, + body: encryptedMsg.body, + timestamp: new Date().getTime() + }; + + if (deviceObjectList[i].relay !== undefined) + jsonData[i].relay = deviceObjectList[i].relay; + }); }); } + for (var i = 0; i < deviceObjectList.length; i++) promises[i] = addEncryptionFor(i); return Promise.all(promises).then(function() { @@ -575,6 +589,8 @@ window.textsecure.sendMessage = function() { } var registerError = function(number, message, error) { + if (error.humanError) + message = error.humanError; errors[errors.length] = { number: number, reason: message, error: error }; numberCompleted(); } diff --git a/js/options.js b/js/options.js index e0082f985..562b413de 100644 --- a/js/options.js +++ b/js/options.js @@ -100,7 +100,11 @@ $('#init-go').click(function() { registrationDone(); } }).catch(function(error) { - alert(error.human_error); + //TODO: No alerts... + if (error.humanError) + alert(error.humanError); + else + alert(error); //XXX }); }); diff --git a/js/webcrypto.js b/js/webcrypto.js index 1394ea7dc..2092f47f1 100644 --- a/js/webcrypto.js +++ b/js/webcrypto.js @@ -23,7 +23,7 @@ window.crypto.subtle = (function() { var StaticArrayBufferProto = new ArrayBuffer().__proto__; function assertIsArrayBuffer(thing) { if (thing !== Object(thing) || thing.__proto__ != StaticArrayBufferProto) - throw new Error("WARNING: Needed a ArrayBuffer"); + throw new Error("Needed a ArrayBuffer"); } // private implementation functions