Log more info w/http errors, resilient to invalid group members (#1968)

* api.js: HttpError now preserves more of original error info

* Allow invalid conversation to be added to ConversationController

If a number we don't believe is valid comes in as part of a group, we
fall apart. We event prevent display of that conversation. Because we
have 'isValid()' protections in place for the places we create contacts
from user input in desktop (the search bar), we can temporarily add an
invalid contact to our collection (not saving it to the database) to
unblock this group scenario.

Still investigating what kind of phone number is valid in a mobile app
but not valid for us.

* Finish the debuggable error support

* Fix logging in the case of an invalid number
This commit is contained in:
Scott Nonnenberg 2018-01-12 16:19:26 -08:00 committed by GitHub
parent 177dfb3220
commit ce01eb7913
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 10 deletions

View file

@ -109,8 +109,18 @@
type: type
});
conversation.initialPromise = new Promise(function(resolve, reject) {
var deferred = conversation.save();
if (!conversation.isValid()) {
var validationError = conversation.validationError || {};
console.log(
'Contact is not valid. Not saving, but adding to collection:',
conversation.idForLogging(),
validationError.stack
);
return resolve(conversation);
}
var deferred = conversation.save();
if (!deferred) {
console.log('Conversation save failed! ', id, type);
return reject(new Error('getOrCreate: Conversation save failed'));

View file

@ -76,7 +76,8 @@ var TextSecureServer = (function() {
}
if (options.user && options.password) {
fetchOptions.headers["Authorization"] = "Basic " + btoa(getString(options.user) + ":" + getString(options.password));
fetchOptions.headers["Authorization"] =
"Basic " + btoa(getString(options.user) + ":" + getString(options.password));
}
if (options.contentType) {
fetchOptions.headers["Content-Type"] = options.contentType;
@ -93,13 +94,21 @@ var TextSecureServer = (function() {
}
return resultPromise.then(function(result) {
if (options.responseType === 'arraybuffer') {
result = result.buffer.slice(result.byteOffset, result.byteOffset + result.byteLength);
result = result.buffer.slice(
result.byteOffset,
result.byteOffset + result.byteLength
);
}
if (options.responseType === 'json') {
if (options.validateResponse) {
if (!validateResponse(result, options.validateResponse)) {
console.log(options.type, url, response.status, 'Error');
reject(HTTPError(response.status, result, options.stack));
reject(HTTPError(
'promise_ajax: invalid response',
response.status,
result,
options.stack
));
}
}
}
@ -108,13 +117,18 @@ var TextSecureServer = (function() {
resolve(result, response.status);
} else {
console.log(options.type, url, response.status, 'Error');
reject(HTTPError(response.status, result, options.stack));
reject(HTTPError(
'promise_ajax: error response',
response.status,
result,
options.stack
));
}
});
}).catch(function(e) {
console.log(options.type, url, 0, 'Error');
console.log(e);
reject(HTTPError(0, e.toString(), options.stack));
var stack = e.stack + '\nInitial stack:\n' + options.stack;
reject(HTTPError('promise_ajax catch', 0, e.toString(), stack));
});
});
}
@ -141,14 +155,14 @@ var TextSecureServer = (function() {
return retry_ajax(url, options);
}
function HTTPError(code, response, stack) {
function HTTPError(message, code, response, stack) {
if (code > 999 || code < 100) {
code = -1;
}
var e = new Error();
var e = new Error(message + '; code: ' + code);
e.name = 'HTTPError';
e.code = code;
e.stack = stack;
e.stack += '\nOriginal stack:\n' + stack;
if (response) {
e.response = response;
}