Convert throwHumanError to custom error type

Now with 200% more helpful stack traces.

// FREEBIE
This commit is contained in:
lilia 2015-07-10 11:28:47 -07:00
parent e86c40d3a8
commit 3711e0a6cd
6 changed files with 111 additions and 128 deletions

View file

@ -120,7 +120,7 @@
function onError(ev) { function onError(ev) {
var e = ev.error; 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(); extension.install();
return; return;
} }
@ -129,6 +129,7 @@
console.log(e); console.log(e);
throw e; throw e;
} }
var envelope = ev.proto; var envelope = ev.proto;
var message = initIncomingMessage(envelope.source, envelope.timestamp.toNumber()); var message = initIncomingMessage(envelope.source, envelope.timestamp.toNumber());
if (e.name === 'IncomingIdentityKeyError') { if (e.name === 'IncomingIdentityKeyError') {

View file

@ -38998,6 +38998,7 @@ TextSecureServer = function () {
* jsonData: JSON data sent in the request body * jsonData: JSON data sent in the request body
*/ */
function ajax(url, options) { function ajax(url, options) {
var error = new Error(); // just in case, save stack here.
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open(options.type, url, true /*async*/); xhr.open(options.type, url, true /*async*/);
@ -39023,21 +39024,27 @@ TextSecureServer = function () {
if ( 0 <= xhr.status && xhr.status < 400) { if ( 0 <= xhr.status && xhr.status < 400) {
options.success(result, xhr.status); options.success(result, xhr.status);
} else { } else {
options.error(result, xhr.status); options.error(HTTPError(xhr.status, result, error.stack));
} }
}; };
xhr.onerror = function() { xhr.onerror = function() {
options.error(null, xhr.status); options.error(HTTPError(xhr.status, null, error.stack));
}; };
xhr.send( options.data || null ); xhr.send( options.data || null );
} }
function throwHumanError (error, type, humanError) { function HTTPError(code, response, stack) {
var e = new Error(error); if (code > 999 || code < 100) {
if (type !== undefined) code = -1;
e.name = type; }
e.humanError = humanError; var e = new Error(message);
throw e; e.name = 'HTTPError';
e.code = code;
e.stack = stack;
if (response) {
e.response = response;
}
return e;
} }
var doAjax = function (param) { var doAjax = function (param) {
@ -39059,47 +39066,42 @@ TextSecureServer = function () {
user : param.user, user : param.user,
password : param.password, password : param.password,
success : resolve, success : resolve,
error : function(result, code) { error : function(e) {
var code = e.code;
if (code === 200) { if (code === 200) {
// happens sometimes when we get no response // happens sometimes when we get no response
// (TODO: Fix server to return 204? instead) // (TODO: Fix server to return 204? instead)
resolve(null); resolve(null);
return; return;
} }
if (code > 999 || code < 100) var message;
code = -1;
try {
switch (code) { switch (code) {
case -1: case -1:
throwHumanError(code, "HTTPError", message = "Failed to connect to the server, please check your network connection.";
"Failed to connect to the server, please check your network connection."); break;
case 413: case 413:
throwHumanError(code, "HTTPError", message = "Rate limit exceeded, please try again later.";
"Rate limit exceeded, please try again later."); break;
case 403: case 403:
throwHumanError(code, "HTTPError", message = "Invalid code, please try again.";
"Invalid code, please try again."); break;
case 417: case 417:
// TODO: This shouldn't be a thing?, but its in the API doc? // TODO: This shouldn't be a thing?, but its in the API doc?
throwHumanError(code, "HTTPError", message = "Number already registered.";
"Number already registered."); break;
case 401: case 401:
throwHumanError(code, "HTTPError", case 403:
"Invalid authentication, most likely someone re-registered and invalidated our registration."); message = "Invalid authentication, most likely someone re-registered and invalidated our registration.";
break;
case 404: case 404:
throwHumanError(code, "HTTPError", message = "Number is not registered with TextSecure.";
"Number is not registered with TextSecure."); break;
default: default:
throwHumanError(code, "HTTPError", message = "The server rejected our query, please file a bug report.";
"The server rejected our query, please file a bug report.");
}
} catch (e) {
if (result) {
e.response = result;
} }
e.message = message
reject(e); reject(e);
} }
}
}); });
}); });
}; };
@ -39244,14 +39246,8 @@ TextSecureServer = function () {
contentType: "application/octet-stream", contentType: "application/octet-stream",
success : resolve, success : resolve,
error : function(result, code) { error : function(e) {
if (code > 999 || code < 100) e.message = 'Failed to download attachment';
code = -1;
var e = new Error(code);
e.name = "HTTPError";
if (result)
e.response = result;
reject(e); reject(e);
} }
}); });
@ -39282,14 +39278,8 @@ TextSecureServer = function () {
reject(e); reject(e);
} }
}, },
error : function(result, code) { error : function(e) {
if (code > 999 || code < 100) e.message = 'Failed to upload attachment';
code = -1;
var e = new Error(code);
e.name = "HTTPError";
if (result)
e.response = result;
reject(e); reject(e);
} }
}); });
@ -39533,7 +39523,7 @@ function generateKeys(count, progressCallback) {
if (e.code === 1006) { if (e.code === 1006) {
// possible 403. Make an request to confirm // possible 403. Make an request to confirm
TextSecureServer.getDevices(textsecure.storage.user.getNumber()).catch(function(e) { 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'); var ev = new Event('error');
ev.error = e; ev.error = e;
eventTarget.dispatchEvent(ev); eventTarget.dispatchEvent(ev);
@ -39919,12 +39909,12 @@ window.textsecure.messaging = function() {
numberCompleted(); numberCompleted();
}); });
}).catch(function(error) { }).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) if (!recurse)
return registerError(number, "Hit retry limit attempting to reload device list", error); return registerError(number, "Hit retry limit attempting to reload device list", error);
var p; var p;
if (error.message == 409) { if (error.code == 409) {
p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices); p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices);
} else { } else {
p = Promise.all(error.response.staleDevices.map(function(deviceId) { p = Promise.all(error.response.staleDevices.map(function(deviceId) {
@ -39933,7 +39923,7 @@ window.textsecure.messaging = function() {
} }
p.then(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) getKeysForNumber(number, resetDevices)
.then(reloadDevicesAndSend(number, false)) .then(reloadDevicesAndSend(number, false))
.catch(function(error) { .catch(function(error) {

View file

@ -82,7 +82,7 @@
bg.openInbox(); bg.openInbox();
window.close(); window.close();
}).catch(function(e) { }).catch(function(e) {
if (e.name === 'HTTPError' && e.message == 411) { if (e.name === 'HTTPError' && e.code == 411) {
$('.progress-dialog').hide(); $('.progress-dialog').hide();
$('.error-dialog').show(); $('.error-dialog').show();
} }

View file

@ -53,6 +53,7 @@ TextSecureServer = function () {
* jsonData: JSON data sent in the request body * jsonData: JSON data sent in the request body
*/ */
function ajax(url, options) { function ajax(url, options) {
var error = new Error(); // just in case, save stack here.
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open(options.type, url, true /*async*/); xhr.open(options.type, url, true /*async*/);
@ -78,21 +79,27 @@ TextSecureServer = function () {
if ( 0 <= xhr.status && xhr.status < 400) { if ( 0 <= xhr.status && xhr.status < 400) {
options.success(result, xhr.status); options.success(result, xhr.status);
} else { } else {
options.error(result, xhr.status); options.error(HTTPError(xhr.status, result, error.stack));
} }
}; };
xhr.onerror = function() { xhr.onerror = function() {
options.error(null, xhr.status); options.error(HTTPError(xhr.status, null, error.stack));
}; };
xhr.send( options.data || null ); xhr.send( options.data || null );
} }
function throwHumanError (error, type, humanError) { function HTTPError(code, response, stack) {
var e = new Error(error); if (code > 999 || code < 100) {
if (type !== undefined) code = -1;
e.name = type; }
e.humanError = humanError; var e = new Error(message);
throw e; e.name = 'HTTPError';
e.code = code;
e.stack = stack;
if (response) {
e.response = response;
}
return e;
} }
var doAjax = function (param) { var doAjax = function (param) {
@ -114,47 +121,42 @@ TextSecureServer = function () {
user : param.user, user : param.user,
password : param.password, password : param.password,
success : resolve, success : resolve,
error : function(result, code) { error : function(e) {
var code = e.code;
if (code === 200) { if (code === 200) {
// happens sometimes when we get no response // happens sometimes when we get no response
// (TODO: Fix server to return 204? instead) // (TODO: Fix server to return 204? instead)
resolve(null); resolve(null);
return; return;
} }
if (code > 999 || code < 100) var message;
code = -1;
try {
switch (code) { switch (code) {
case -1: case -1:
throwHumanError(code, "HTTPError", message = "Failed to connect to the server, please check your network connection.";
"Failed to connect to the server, please check your network connection."); break;
case 413: case 413:
throwHumanError(code, "HTTPError", message = "Rate limit exceeded, please try again later.";
"Rate limit exceeded, please try again later."); break;
case 403: case 403:
throwHumanError(code, "HTTPError", message = "Invalid code, please try again.";
"Invalid code, please try again."); break;
case 417: case 417:
// TODO: This shouldn't be a thing?, but its in the API doc? // TODO: This shouldn't be a thing?, but its in the API doc?
throwHumanError(code, "HTTPError", message = "Number already registered.";
"Number already registered."); break;
case 401: case 401:
throwHumanError(code, "HTTPError", case 403:
"Invalid authentication, most likely someone re-registered and invalidated our registration."); message = "Invalid authentication, most likely someone re-registered and invalidated our registration.";
break;
case 404: case 404:
throwHumanError(code, "HTTPError", message = "Number is not registered with TextSecure.";
"Number is not registered with TextSecure."); break;
default: default:
throwHumanError(code, "HTTPError", message = "The server rejected our query, please file a bug report.";
"The server rejected our query, please file a bug report.");
}
} catch (e) {
if (result) {
e.response = result;
} }
e.message = message
reject(e); reject(e);
} }
}
}); });
}); });
}; };
@ -299,14 +301,8 @@ TextSecureServer = function () {
contentType: "application/octet-stream", contentType: "application/octet-stream",
success : resolve, success : resolve,
error : function(result, code) { error : function(e) {
if (code > 999 || code < 100) e.message = 'Failed to download attachment';
code = -1;
var e = new Error(code);
e.name = "HTTPError";
if (result)
e.response = result;
reject(e); reject(e);
} }
}); });
@ -337,14 +333,8 @@ TextSecureServer = function () {
reject(e); reject(e);
} }
}, },
error : function(result, code) { error : function(e) {
if (code > 999 || code < 100) e.message = 'Failed to upload attachment';
code = -1;
var e = new Error(code);
e.name = "HTTPError";
if (result)
e.response = result;
reject(e); reject(e);
} }
}); });

View file

@ -37,10 +37,12 @@
if (e.code === 1006) { if (e.code === 1006) {
// possible 403. Make an request to confirm // possible 403. Make an request to confirm
TextSecureServer.getDevices(textsecure.storage.user.getNumber()).catch(function(e) { 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'); var ev = new Event('error');
ev.error = e; ev.error = e;
eventTarget.dispatchEvent(ev); eventTarget.dispatchEvent(ev);
} else {
throw e;
} }
}); });
} }

View file

@ -189,12 +189,12 @@ window.textsecure.messaging = function() {
numberCompleted(); numberCompleted();
}); });
}).catch(function(error) { }).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) if (!recurse)
return registerError(number, "Hit retry limit attempting to reload device list", error); return registerError(number, "Hit retry limit attempting to reload device list", error);
var p; var p;
if (error.message == 409) { if (error.code == 409) {
p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices); p = textsecure.storage.devices.removeDeviceIdsForNumber(number, error.response.extraDevices);
} else { } else {
p = Promise.all(error.response.staleDevices.map(function(deviceId) { p = Promise.all(error.response.staleDevices.map(function(deviceId) {
@ -203,7 +203,7 @@ window.textsecure.messaging = function() {
} }
p.then(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) getKeysForNumber(number, resetDevices)
.then(reloadDevicesAndSend(number, false)) .then(reloadDevicesAndSend(number, false))
.catch(function(error) { .catch(function(error) {