Browse Source

Fixed #214 - Now showing all API errors in modal boxes.

master
Igor Zhukov 11 years ago
parent
commit
8e97680c4f
  1. 26
      app/css/app.css
  2. 22
      app/js/controllers.js
  3. 45
      app/js/lib/mtproto.js
  4. 24
      app/js/services.js
  5. 15
      app/partials/error_modal.html

26
app/css/app.css

@ -2052,6 +2052,32 @@ img.img_fullsize { @@ -2052,6 +2052,32 @@ img.img_fullsize {
font-size: 14px;
line-height: 160%;
}
.error_modal_details textarea {
display: block;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
padding: 0;
font-size: 10px;
line-height: 100%;
white-space: pre-wrap;
padding: 4px;
margin: 10px 0 10px;
word-break: break-all;
word-wrap: break-word;
color: #333333;
background-color: #f5f5f5;
border: 1px solid #cccccc;
border-radius: 4px;
width: 100%;
text-align: left;
}
.error_modal_details div {
padding: 0 20px;
font-size: 13px;
text-align: center;
}
.error_modal_details div a {
color: #999;
}

22
app/js/controllers.js

@ -98,6 +98,7 @@ angular.module('myApp.controllers', []) @@ -98,6 +98,7 @@ angular.module('myApp.controllers', [])
switch (error.type) {
case 'PHONE_NUMBER_INVALID':
$scope.error = {field: 'phone'};
error.handled = true;
break;
}
});
@ -106,10 +107,8 @@ angular.module('myApp.controllers', []) @@ -106,10 +107,8 @@ angular.module('myApp.controllers', [])
switch (error.type) {
case 'PHONE_NUMBER_INVALID':
$scope.error = {field: 'phone'};
error.handled = true;
break;
default:
ErrorService.alert('Unknown error occured', 'Please check your internet connection or install the latest version of Google Chrome browser.');
}
});
}
@ -132,8 +131,10 @@ angular.module('myApp.controllers', []) @@ -132,8 +131,10 @@ angular.module('myApp.controllers', [])
MtpApiManager.invokeApi(method, params, options).then(saveAuth, function (error) {
$scope.progress.enabled = false;
if (error.code == 400 && error.type == 'PHONE_NUMBER_UNOCCUPIED') {
error.handled = true;
return $scope.logIn(true);
} else if (error.code == 400 && error.type == 'PHONE_NUMBER_OCCUPIED') {
error.handled = true;
return $scope.logIn(false);
}
@ -141,12 +142,15 @@ angular.module('myApp.controllers', []) @@ -141,12 +142,15 @@ angular.module('myApp.controllers', [])
switch (error.type) {
case 'FIRSTNAME_INVALID':
$scope.error = {field: 'first_name'};
error.handled = true;
break;
case 'LASTNAME_INVALID':
$scope.error = {field: 'last_name'};
error.handled = true;
break;
case 'PHONE_CODE_INVALID':
$scope.error = {field: 'phone_code'};
error.handled = true;
break;
}
});
@ -313,6 +317,7 @@ angular.module('myApp.controllers', []) @@ -313,6 +317,7 @@ angular.module('myApp.controllers', [])
MtpApiManager.logOut()['finally'](function () {
$location.url('/login');
});
error.handled = true;
}
});
}
@ -1083,12 +1088,6 @@ angular.module('myApp.controllers', []) @@ -1083,12 +1088,6 @@ angular.module('myApp.controllers', [])
}
}).then(function (updateResult) {
onStatedMessage(updateResult);
}, function (error) {
switch (error.code) {
case 400:
ErrorService.alert('Bad photo', 'The photo is invalid, please select another file.');
break;
}
});
})['finally'](function () {
$scope.photo.updating = false;
@ -1121,7 +1120,7 @@ angular.module('myApp.controllers', []) @@ -1121,7 +1120,7 @@ angular.module('myApp.controllers', [])
})
.controller('SettingsModalController', function ($rootScope, $scope, $timeout, AppUsersManager, AppChatsManager, MtpApiManager, AppConfigManager, NotificationsManager, MtpApiFileManager, ApiUpdatesManager, ErrorService) {
.controller('SettingsModalController', function ($rootScope, $scope, $timeout, AppUsersManager, AppChatsManager, MtpApiManager, AppConfigManager, NotificationsManager, MtpApiFileManager, ApiUpdatesManager) {
$scope.profile = {};
@ -1247,13 +1246,16 @@ angular.module('myApp.controllers', []) @@ -1247,13 +1246,16 @@ angular.module('myApp.controllers', [])
switch (error.type) {
case 'FIRSTNAME_INVALID':
$scope.error = {field: 'first_name'};
error.handled = true;
break;
case 'LASTNAME_INVALID':
$scope.error = {field: 'last_name'};
error.handled = true;
break;
case 'NAME_NOT_MODIFIED':
error.handled = true;
$scope.error = {};
break;
}

45
app/js/lib/mtproto.js

@ -2457,7 +2457,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato @@ -2457,7 +2457,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
}).
factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworkerFactory, $q) {
factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworkerFactory, ErrorService, $q) {
var cachedNetworkers = {},
cachedUploadNetworkers = {},
cachedExportPromise = {},
@ -2489,6 +2489,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2489,6 +2489,7 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
AppConfigManager.remove('dc' + baseDcID + '_auth_key');
}
baseDcID = false;
error.handled = true;
});
}
@ -2547,6 +2548,25 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2547,6 +2548,25 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
options = options || {};
var deferred = $q.defer(),
rejectPromise = function (error) {
if (!error) {
error = {type: 'ERROR_EMPTY'};
} else if (!angular.isObject(error)) {
error = {message: error};
}
deferred.reject(error);
if (!options.noErrorBox) {
error.input = method;
error.stack = error.stack || stack;
setTimeout(function () {
if (!error.handled) {
ErrorService.show({error: error});
error.handled = true;
}
}, 100);
}
},
dcID,
networkerPromise;
@ -2558,7 +2578,8 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2558,7 +2578,8 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
});
}
var cachedNetworker;
var cachedNetworker,
stack = false;
networkerPromise.then(function (networker) {
return (cachedNetworker = networker).wrapApiCall(method, params, options).then(
@ -2574,11 +2595,11 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2574,11 +2595,11 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
if (cachedExportPromise[dcID] === undefined) {
var exportDeferred = $q.defer();
mtpInvokeApi('auth.exportAuthorization', {dc_id: dcID}).then(function (exportedAuth) {
mtpInvokeApi('auth.exportAuthorization', {dc_id: dcID}, {noErrorBox: true}).then(function (exportedAuth) {
mtpInvokeApi('auth.importAuthorization', {
id: exportedAuth.id,
bytes: exportedAuth.bytes
}, {dcID: dcID}).then(function () {
}, {dcID: dcID, noErrorBox: true}).then(function () {
exportDeferred.resolve();
}, function (e) {
exportDeferred.reject(e);
@ -2594,10 +2615,10 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2594,10 +2615,10 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
(cachedNetworker = networker).wrapApiCall(method, params, options).then(function (result) {
deferred.resolve(result);
}, function (error) {
deferred.reject(error);
rejectPromise(error);
});
}, function (error) {
deferred.reject(error);
rejectPromise(error);
});
}
else if (error.code == 303) {
@ -2613,19 +2634,25 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker @@ -2613,19 +2634,25 @@ factory('MtpApiManager', function (AppConfigManager, MtpAuthorizer, MtpNetworker
networker.wrapApiCall(method, params, options).then(function (result) {
deferred.resolve(result);
}, function (error) {
deferred.reject(error);
rejectPromise(error);
});
});
}
}
else {
deferred.reject(error);
rejectPromise(error);
}
});
}, function (error) {
deferred.reject(error);
rejectPromise(error);
});
if (!(stack = (stack || (new Error()).stack))) {
try {1 = 0;} catch (e) {
stack = e.stack || '';
}
}
return deferred.promise;
};

24
app/js/services.js

@ -318,7 +318,7 @@ angular.module('myApp.services', []) @@ -318,7 +318,7 @@ angular.module('myApp.services', [])
});
return MtpApiManager.invokeApi('contacts.deleteContacts', {
id: ids
}, function () {
}).then(function () {
angular.forEach(userIDs, function (userID) {
onContactUpdated(userID, false);
});
@ -779,7 +779,7 @@ angular.module('myApp.services', []) @@ -779,7 +779,7 @@ angular.module('myApp.services', [])
}
function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) {
// console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage));
console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage));
return MtpApiManager.invokeApi('messages.getHistory', {
peer: inputPeer,
offset: 0,
@ -926,8 +926,6 @@ angular.module('myApp.services', []) @@ -926,8 +926,6 @@ angular.module('myApp.services', [])
return deletedMessageIDs;
});
}
function processAffectedHistory (inputPeer, affectedHistory, method) {
@ -2798,7 +2796,7 @@ angular.module('myApp.services', []) @@ -2798,7 +2796,7 @@ angular.module('myApp.services', [])
lastOnlineUpdated = offline ? 0 : date;
return MtpApiManager.invokeApi('account.updateStatus', {
offline: offline
});
}, {noErrorBox: true});
}
function checkIDLE() {
@ -3006,16 +3004,30 @@ angular.module('myApp.services', []) @@ -3006,16 +3004,30 @@ angular.module('myApp.services', [])
.service('ErrorService', function ($rootScope, $modal) {
var shownBoxes = 0;
function show (params, options) {
if (shownBoxes >= 2) {
console.log('Skip error box, too many open', shownBoxes, params, options);
return false;
}
options = options || {};
var scope = $rootScope.$new();
angular.extend(scope, params);
return $modal.open({
shownBoxes++;
var modal = $modal.open({
templateUrl: 'partials/error_modal.html',
scope: scope,
windowClass: options.windowClass || 'error_modal_window'
});
modal.result['finally'](function () {
shownBoxes--;
});
return modal;
}
function alert (title, description) {

15
app/partials/error_modal.html

@ -34,6 +34,9 @@ @@ -34,6 +34,9 @@
<span ng-switch-when="PHOTO_INVALID_DIMENSIONS">
The photo dimensions are invalid, please select another file.
</span>
<span ng-switch-when="PHOTO_CROP_SIZE_SMALL">
The photo you provided is too small.
</span>
<span ng-switch-when="ACCOUNT_REQUIRED">
Sorry, there is no <strong>Telegram</strong> account for {{phone | phoneNumber}}<br/><br/>
Please <strong>sign up</strong> using our mobile apps for <a href="https://telegram.org/" target="_blank">iOS</a> or <a href="https://telegram.org/" target="_blank">Android</a>.
@ -47,12 +50,16 @@ @@ -47,12 +50,16 @@
<span ng-switch-when="404">The page was not found.</span>
<span ng-switch-when="420">You are performing too many actions. Please try again later.</span>
<span ng-switch-default>Internal server error occured. Please try again later.</span>
</div>
<div ng-if="error.originalError" ng-switch="showErrorDetails">
<pre ng-switch-when="true"><code>{{error.originalError}}</code></pre>
<a ng-switch-default href="" ng-click="showErrorDetails = true">Click here</a> for technical details.
</div>
</div>
<div ng-if="error" class="error_modal_details" ng-switch="error.detailsShown">
<textarea ng-switch-when="true" rows="3" onclick="this.select()">Method: {{error.input || 'N/A'}}
Result: {{error.originalError || error}}
Stack: {{error.stack}}</textarea>
<div ng-switch-default>
<a href="" ng-click="error.detailsShown = true">Technical details here</a>
</div>
</div>

Loading…
Cancel
Save