diff --git a/app/css/app.css b/app/css/app.css
index 9def9d17..4796c549 100644
--- a/app/css/app.css
+++ b/app/css/app.css
@@ -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;
+}
diff --git a/app/js/controllers.js b/app/js/controllers.js
index 207ac177..6da69c28 100644
--- a/app/js/controllers.js
+++ b/app/js/controllers.js
@@ -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', [])
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', [])
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', [])
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', [])
MtpApiManager.logOut()['finally'](function () {
$location.url('/login');
});
+ error.handled = true;
}
});
}
@@ -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', [])
})
- .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', [])
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;
}
diff --git a/app/js/lib/mtproto.js b/app/js/lib/mtproto.js
index 00cc115d..353fd3da 100644
--- a/app/js/lib/mtproto.js
+++ b/app/js/lib/mtproto.js
@@ -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
AppConfigManager.remove('dc' + baseDcID + '_auth_key');
}
baseDcID = false;
+ error.handled = true;
});
}
@@ -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
});
}
- 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
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
(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
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;
};
diff --git a/app/js/services.js b/app/js/services.js
index c461fc1b..b81ebeff 100644
--- a/app/js/services.js
+++ b/app/js/services.js
@@ -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', [])
}
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', [])
return deletedMessageIDs;
});
-
-
}
function processAffectedHistory (inputPeer, affectedHistory, method) {
@@ -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', [])
.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) {
diff --git a/app/partials/error_modal.html b/app/partials/error_modal.html
index f492053c..314502f3 100644
--- a/app/partials/error_modal.html
+++ b/app/partials/error_modal.html
@@ -34,6 +34,9 @@
The photo dimensions are invalid, please select another file.
+
+ The photo you provided is too small.
+
Sorry, there is no Telegram account for {{phone | phoneNumber}}
Please sign up using our mobile apps for iOS or Android.
@@ -47,12 +50,16 @@
The page was not found.
You are performing too many actions. Please try again later.
Internal server error occured. Please try again later.
+
-
-
{{error.originalError}}
-
Click here for technical details.
-
+
+