From 3711e0a6cdb8455c1c552f74b6dff8d4cb51e589 Mon Sep 17 00:00:00 2001 From: lilia Date: Fri, 10 Jul 2015 11:28:47 -0700 Subject: [PATCH] Convert throwHumanError to custom error type Now with 200% more helpful stack traces. // FREEBIE --- js/background.js | 3 +- js/libtextsecure.js | 116 ++++++++++++++---------------- js/options.js | 2 +- libtextsecure/api.js | 108 +++++++++++++--------------- libtextsecure/message_receiver.js | 4 +- libtextsecure/sendmessage.js | 6 +- 6 files changed, 111 insertions(+), 128 deletions(-) diff --git a/js/background.js b/js/background.js index 01bfac79..3352f005 100644 --- a/js/background.js +++ b/js/background.js @@ -120,7 +120,7 @@ function onError(ev) { var e = ev.error; - if (e.name === 'HTTPError' && (e.message == 401 || e.message == 403)) { + if (e.name === 'HTTPError' && (e.code == 401 || e.code == 403)) { extension.install(); return; } @@ -129,6 +129,7 @@ console.log(e); throw e; } + var envelope = ev.proto; var message = initIncomingMessage(envelope.source, envelope.timestamp.toNumber()); if (e.name === 'IncomingIdentityKeyError') { diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 9c2dac64..0cca668a 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -38998,6 +38998,7 @@ TextSecureServer = function () { * jsonData: JSON data sent in the request body */ function ajax(url, options) { + var error = new Error(); // just in case, save stack here. var xhr = new XMLHttpRequest(); xhr.open(options.type, url, true /*async*/); @@ -39023,21 +39024,27 @@ TextSecureServer = function () { if ( 0 <= xhr.status && xhr.status < 400) { options.success(result, xhr.status); } else { - options.error(result, xhr.status); + options.error(HTTPError(xhr.status, result, error.stack)); } }; xhr.onerror = function() { - options.error(null, xhr.status); + options.error(HTTPError(xhr.status, null, error.stack)); }; xhr.send( options.data || null ); } - function throwHumanError (error, type, humanError) { - var e = new Error(error); - if (type !== undefined) - e.name = type; - e.humanError = humanError; - throw e; + function HTTPError(code, response, stack) { + if (code > 999 || code < 100) { + code = -1; + } + var e = new Error(message); + e.name = 'HTTPError'; + e.code = code; + e.stack = stack; + if (response) { + e.response = response; + } + return e; } var doAjax = function (param) { @@ -39059,46 +39066,41 @@ TextSecureServer = function () { user : param.user, password : param.password, success : resolve, - error : function(result, code) { + error : function(e) { + var code = e.code; if (code === 200) { // happens sometimes when we get no response // (TODO: Fix server to return 204? instead) resolve(null); return; } - if (code > 999 || code < 100) - code = -1; - try { - switch (code) { - case -1: - throwHumanError(code, "HTTPError", - "Failed to connect to the server, please check your network connection."); - case 413: - throwHumanError(code, "HTTPError", - "Rate limit exceeded, please try again later."); - case 403: - throwHumanError(code, "HTTPError", - "Invalid code, please try again."); - case 417: - // TODO: This shouldn't be a thing?, but its in the API doc? - throwHumanError(code, "HTTPError", - "Number already registered."); - case 401: - throwHumanError(code, "HTTPError", - "Invalid authentication, most likely someone re-registered and invalidated our registration."); - case 404: - throwHumanError(code, "HTTPError", - "Number is not registered with TextSecure."); - default: - throwHumanError(code, "HTTPError", - "The server rejected our query, please file a bug report."); - } - } catch (e) { - if (result) { - e.response = result; - } - reject(e); + var message; + switch (code) { + case -1: + message = "Failed to connect to the server, please check your network connection."; + break; + case 413: + message = "Rate limit exceeded, please try again later."; + break; + case 403: + message = "Invalid code, please try again."; + break; + case 417: + // TODO: This shouldn't be a thing?, but its in the API doc? + message = "Number already registered."; + break; + case 401: + case 403: + message = "Invalid authentication, most likely someone re-registered and invalidated our registration."; + break; + case 404: + message = "Number is not registered with TextSecure."; + break; + default: + message = "The server rejected our query, please file a bug report."; } + e.message = message + reject(e); } }); }); @@ -39244,16 +39246,10 @@ TextSecureServer = function () { contentType: "application/octet-stream", success : resolve, - error : function(result, code) { - if (code > 999 || code < 100) - code = -1; - - var e = new Error(code); - e.name = "HTTPError"; - if (result) - e.response = result; - reject(e); - } + error : function(e) { + e.message = 'Failed to download attachment'; + reject(e); + } }); }); }); @@ -39282,14 +39278,8 @@ TextSecureServer = function () { reject(e); } }, - error : function(result, code) { - if (code > 999 || code < 100) - code = -1; - - var e = new Error(code); - e.name = "HTTPError"; - if (result) - e.response = result; + error : function(e) { + e.message = 'Failed to upload attachment'; reject(e); } }); @@ -39533,7 +39523,7 @@ function generateKeys(count, progressCallback) { if (e.code === 1006) { // possible 403. Make an request to confirm TextSecureServer.getDevices(textsecure.storage.user.getNumber()).catch(function(e) { - if (e.name === 'HTTPError' && (e.message == 401 || e.message == 403)) { + if (e.name === 'HTTPError' && (e.code == 401 || e.code == 403)) { var ev = new Event('error'); ev.error = e; eventTarget.dispatchEvent(ev); @@ -39919,12 +39909,12 @@ window.textsecure.messaging = function() { numberCompleted(); }); }).catch(function(error) { - if (error instanceof Error && error.name == "HTTPError" && (error.message == 410 || error.message == 409)) { + if (error instanceof Error && error.name == "HTTPError" && (error.code == 410 || error.code == 409)) { if (!recurse) return registerError(number, "Hit retry limit attempting to reload device list", error); var p; - if (error.message == 409) { + if (error.code == 409) { p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices); } else { p = Promise.all(error.response.staleDevices.map(function(deviceId) { @@ -39933,7 +39923,7 @@ window.textsecure.messaging = function() { } p.then(function() { - var resetDevices = ((error.message == 410) ? error.response.staleDevices : error.response.missingDevices); + var resetDevices = ((error.code == 410) ? error.response.staleDevices : error.response.missingDevices); getKeysForNumber(number, resetDevices) .then(reloadDevicesAndSend(number, false)) .catch(function(error) { diff --git a/js/options.js b/js/options.js index 163b17e9..b405fe85 100644 --- a/js/options.js +++ b/js/options.js @@ -82,7 +82,7 @@ bg.openInbox(); window.close(); }).catch(function(e) { - if (e.name === 'HTTPError' && e.message == 411) { + if (e.name === 'HTTPError' && e.code == 411) { $('.progress-dialog').hide(); $('.error-dialog').show(); } diff --git a/libtextsecure/api.js b/libtextsecure/api.js index f061b02a..c4fe4404 100644 --- a/libtextsecure/api.js +++ b/libtextsecure/api.js @@ -53,6 +53,7 @@ TextSecureServer = function () { * jsonData: JSON data sent in the request body */ function ajax(url, options) { + var error = new Error(); // just in case, save stack here. var xhr = new XMLHttpRequest(); xhr.open(options.type, url, true /*async*/); @@ -78,21 +79,27 @@ TextSecureServer = function () { if ( 0 <= xhr.status && xhr.status < 400) { options.success(result, xhr.status); } else { - options.error(result, xhr.status); + options.error(HTTPError(xhr.status, result, error.stack)); } }; xhr.onerror = function() { - options.error(null, xhr.status); + options.error(HTTPError(xhr.status, null, error.stack)); }; xhr.send( options.data || null ); } - function throwHumanError (error, type, humanError) { - var e = new Error(error); - if (type !== undefined) - e.name = type; - e.humanError = humanError; - throw e; + function HTTPError(code, response, stack) { + if (code > 999 || code < 100) { + code = -1; + } + var e = new Error(message); + e.name = 'HTTPError'; + e.code = code; + e.stack = stack; + if (response) { + e.response = response; + } + return e; } var doAjax = function (param) { @@ -114,46 +121,41 @@ TextSecureServer = function () { user : param.user, password : param.password, success : resolve, - error : function(result, code) { + error : function(e) { + var code = e.code; if (code === 200) { // happens sometimes when we get no response // (TODO: Fix server to return 204? instead) resolve(null); return; } - if (code > 999 || code < 100) - code = -1; - try { - switch (code) { - case -1: - throwHumanError(code, "HTTPError", - "Failed to connect to the server, please check your network connection."); - case 413: - throwHumanError(code, "HTTPError", - "Rate limit exceeded, please try again later."); - case 403: - throwHumanError(code, "HTTPError", - "Invalid code, please try again."); - case 417: - // TODO: This shouldn't be a thing?, but its in the API doc? - throwHumanError(code, "HTTPError", - "Number already registered."); - case 401: - throwHumanError(code, "HTTPError", - "Invalid authentication, most likely someone re-registered and invalidated our registration."); - case 404: - throwHumanError(code, "HTTPError", - "Number is not registered with TextSecure."); - default: - throwHumanError(code, "HTTPError", - "The server rejected our query, please file a bug report."); - } - } catch (e) { - if (result) { - e.response = result; - } - reject(e); + var message; + switch (code) { + case -1: + message = "Failed to connect to the server, please check your network connection."; + break; + case 413: + message = "Rate limit exceeded, please try again later."; + break; + case 403: + message = "Invalid code, please try again."; + break; + case 417: + // TODO: This shouldn't be a thing?, but its in the API doc? + message = "Number already registered."; + break; + case 401: + case 403: + message = "Invalid authentication, most likely someone re-registered and invalidated our registration."; + break; + case 404: + message = "Number is not registered with TextSecure."; + break; + default: + message = "The server rejected our query, please file a bug report."; } + e.message = message + reject(e); } }); }); @@ -299,16 +301,10 @@ TextSecureServer = function () { contentType: "application/octet-stream", success : resolve, - error : function(result, code) { - if (code > 999 || code < 100) - code = -1; - - var e = new Error(code); - e.name = "HTTPError"; - if (result) - e.response = result; - reject(e); - } + error : function(e) { + e.message = 'Failed to download attachment'; + reject(e); + } }); }); }); @@ -337,14 +333,8 @@ TextSecureServer = function () { reject(e); } }, - error : function(result, code) { - if (code > 999 || code < 100) - code = -1; - - var e = new Error(code); - e.name = "HTTPError"; - if (result) - e.response = result; + error : function(e) { + e.message = 'Failed to upload attachment'; reject(e); } }); diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index a96a2ede..114c8cc3 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -37,10 +37,12 @@ if (e.code === 1006) { // possible 403. Make an request to confirm TextSecureServer.getDevices(textsecure.storage.user.getNumber()).catch(function(e) { - if (e.name === 'HTTPError' && (e.message == 401 || e.message == 403)) { + if (e.name === 'HTTPError' && (e.code == 401 || e.code == 403)) { var ev = new Event('error'); ev.error = e; eventTarget.dispatchEvent(ev); + } else { + throw e; } }); } diff --git a/libtextsecure/sendmessage.js b/libtextsecure/sendmessage.js index 89ad3c37..489a5cba 100644 --- a/libtextsecure/sendmessage.js +++ b/libtextsecure/sendmessage.js @@ -189,12 +189,12 @@ window.textsecure.messaging = function() { numberCompleted(); }); }).catch(function(error) { - if (error instanceof Error && error.name == "HTTPError" && (error.message == 410 || error.message == 409)) { + if (error instanceof Error && error.name == "HTTPError" && (error.code == 410 || error.code == 409)) { if (!recurse) return registerError(number, "Hit retry limit attempting to reload device list", error); var p; - if (error.message == 409) { + if (error.code == 409) { p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices); } else { p = Promise.all(error.response.staleDevices.map(function(deviceId) { @@ -203,7 +203,7 @@ window.textsecure.messaging = function() { } p.then(function() { - var resetDevices = ((error.message == 410) ? error.response.staleDevices : error.response.missingDevices); + var resetDevices = ((error.code == 410) ? error.response.staleDevices : error.response.missingDevices); getKeysForNumber(number, resetDevices) .then(reloadDevicesAndSend(number, false)) .catch(function(error) {