You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/04/29 20:58:56 UTC

[14/19] guacamole-client git commit: GUACAMOLE-526: Handle rejections for absolutely all promises.

GUACAMOLE-526: Handle rejections for absolutely all promises.

Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/266b445c
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/266b445c
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/266b445c

Branch: refs/heads/master
Commit: 266b445c217984fdb59048c09b736098776f6a1f
Parents: f6d5e56
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 22:15:17 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 22:15:17 2018 -0700

----------------------------------------------------------------------
 .../app/auth/service/authenticationService.js   |  4 +-
 .../app/client/controllers/clientController.js  | 12 +++--
 .../app/client/directives/guacFileBrowser.js    |  2 +-
 .../webapp/app/client/types/ManagedClient.js    |  7 +--
 .../app/client/types/ManagedFileUpload.js       |  7 +--
 .../webapp/app/form/directives/formField.js     |  5 +-
 .../app/groupList/directives/guacGroupList.js   |  3 +-
 .../app/home/controllers/homeController.js      |  3 +-
 .../app/index/controllers/indexController.js    |  2 +-
 .../webapp/app/list/directives/guacUserItem.js  |  2 +-
 .../main/webapp/app/login/directives/login.js   |  5 +-
 .../controllers/manageConnectionController.js   | 57 +++++---------------
 .../manageConnectionGroupController.js          | 45 +++-------------
 .../manageSharingProfileController.js           | 53 ++++--------------
 .../manage/controllers/manageUserController.js  | 56 +++++--------------
 .../app/navigation/directives/guacUserMenu.js   |  7 ++-
 .../app/navigation/services/userPageService.js  | 15 +++---
 .../app/rest/services/dataSourceService.js      | 13 ++---
 .../directives/guacSettingsConnectionHistory.js |  7 +--
 .../directives/guacSettingsConnections.js       | 17 ++----
 .../directives/guacSettingsPreferences.js       | 21 +++-----
 .../settings/directives/guacSettingsSessions.js | 31 ++---------
 .../settings/directives/guacSettingsUsers.js    | 20 ++-----
 23 files changed, 118 insertions(+), 276 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/auth/service/authenticationService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/auth/service/authenticationService.js b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
index f4a24f9..a5c3ee4 100644
--- a/guacamole/src/main/webapp/app/auth/service/authenticationService.js
+++ b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
@@ -190,7 +190,7 @@ angular.module('auth').factory('authenticationService', ['$injector',
         })
 
         // If authentication fails, propogate failure to returned promise
-        ['catch'](function authenticationFailed(error) {
+        ['catch'](requestService.createErrorCallback(function authenticationFailed(error) {
 
             // Request credentials if provided credentials were invalid
             if (error.type === Error.Type.INVALID_CREDENTIALS)
@@ -203,7 +203,7 @@ angular.module('auth').factory('authenticationService', ['$injector',
             // Authentication failed
             throw error;
 
-        });
+        }));
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/client/controllers/clientController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js
index e89f241..cf4ba5b 100644
--- a/guacamole/src/main/webapp/app/client/controllers/clientController.js
+++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js
@@ -37,6 +37,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
     var guacNotification      = $injector.get('guacNotification');
     var iconService           = $injector.get('iconService');
     var preferenceService     = $injector.get('preferenceService');
+    var requestService        = $injector.get('requestService');
     var tunnelService         = $injector.get('tunnelService');
     var userPageService       = $injector.get('userPageService');
 
@@ -161,7 +162,9 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
         name      : "CLIENT.ACTION_LOGOUT",
         className : "logout button",
         callback  : function logoutCallback() {
-            authenticationService.logout()['finally'](function logoutComplete() {
+            authenticationService.logout()
+            ['catch'](requestService.IGNORE)
+            ['finally'](function logoutComplete() {
                 $location.url('/');
             });
         }
@@ -188,7 +191,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
             };
         }
 
-    });
+    }, requestService.WARN);
 
     /**
      * Action which replaces the current client with a newly-connected client.
@@ -466,7 +469,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
         tunnelService.getSharingProfiles(uuid)
         .then(function sharingProfilesRetrieved(sharingProfiles) {
             $scope.sharingProfiles = sharingProfiles;
-        });
+        }, requestService.WARN);
 
     });
 
@@ -614,6 +617,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
 
         // Re-authenticate to verify auth status at end of connection
         authenticationService.updateCurrentToken($location.search())
+        ['catch'](requestService.IGNORE)
 
         // Show the requested status once the authentication check has finished
         ['finally'](function authenticationCheckComplete() {
@@ -714,7 +718,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
             // Sync with local clipboard
             clipboardService.getLocalClipboard().then(function clipboardRead(data) {
                 $scope.$broadcast('guacClipboard', data);
-            })['catch'](angular.noop);
+            }, angular.noop);
 
             // Hide status notification
             guacNotification.showStatus(false);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js
index 5789d5f..fe1a5e2 100644
--- a/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js
+++ b/guacamole/src/main/webapp/app/client/directives/guacFileBrowser.js
@@ -272,7 +272,7 @@ angular.module('client').directive('guacFileBrowser', [function guacFileBrowser(
 
                 });
 
-            }); // end retrieve file template
+            }, angular.noop); // end retrieve file template
 
             // Refresh file browser when any upload completes
             $scope.$on('guacUploadComplete', function uploadComplete(event, filename) {

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/client/types/ManagedClient.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/types/ManagedClient.js b/guacamole/src/main/webapp/app/client/types/ManagedClient.js
index 32acd8d..e998445 100644
--- a/guacamole/src/main/webapp/app/client/types/ManagedClient.js
+++ b/guacamole/src/main/webapp/app/client/types/ManagedClient.js
@@ -42,6 +42,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
     var authenticationService  = $injector.get('authenticationService');
     var connectionGroupService = $injector.get('connectionGroupService');
     var connectionService      = $injector.get('connectionService');
+    var requestService         = $injector.get('requestService');
     var tunnelService          = $injector.get('tunnelService');
     var guacAudio              = $injector.get('guacAudio');
     var guacHistory            = $injector.get('guacHistory');
@@ -514,7 +515,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
             connectionService.getConnection(clientIdentifier.dataSource, clientIdentifier.id)
             .then(function connectionRetrieved(connection) {
                 managedClient.name = managedClient.title = connection.name;
-            });
+            }, requestService.WARN);
         }
         
         // If using a connection group, pull connection name
@@ -522,7 +523,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
             connectionGroupService.getConnectionGroup(clientIdentifier.dataSource, clientIdentifier.id)
             .then(function connectionGroupRetrieved(group) {
                 managedClient.name = managedClient.title = group.name;
-            });
+            }, requestService.WARN);
         }
 
         return managedClient;
@@ -634,7 +635,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
         credentialRequest.then(function sharingCredentialsReceived(sharingCredentials) {
             client.shareLinks[sharingProfile.identifier] =
                 ManagedShareLink.getInstance(sharingProfile, sharingCredentials);
-        });
+        }, requestService.WARN);
 
         return credentialRequest;
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js b/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js
index 82bface..56587fc 100644
--- a/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js
+++ b/guacamole/src/main/webapp/app/client/types/ManagedFileUpload.js
@@ -28,7 +28,8 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector'
     var ManagedFileTransferState = $injector.get('ManagedFileTransferState');
 
     // Required services
-    var tunnelService = $injector.get('tunnelService');
+    var requestService = $injector.get('requestService');
+    var tunnelService  = $injector.get('tunnelService');
 
     /**
      * Object which serves as a surrogate interface, encapsulating a Guacamole
@@ -171,7 +172,7 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector'
             },
 
             // Notify if upload fails
-            function uploadFailed(error) {
+            requestService.createErrorCallback(function uploadFailed(error) {
 
                 // Use provide status code if the error is coming from the stream
                 if (error.type === Error.Type.STREAM_ERROR)
@@ -185,7 +186,7 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector'
                         ManagedFileTransferState.StreamState.ERROR,
                         Guacamole.Status.Code.INTERNAL_ERROR);
 
-            });
+            }));
 
             // Ignore all further acks
             stream.onack = null;

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/form/directives/formField.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/form/directives/formField.js b/guacamole/src/main/webapp/app/form/directives/formField.js
index 31be836..15bde94 100644
--- a/guacamole/src/main/webapp/app/form/directives/formField.js
+++ b/guacamole/src/main/webapp/app/form/directives/formField.js
@@ -60,6 +60,7 @@ angular.module('form').directive('guacFormField', [function formField() {
         controller: ['$scope', '$injector', '$element', function formFieldController($scope, $injector, $element) {
 
             // Required services
+            var $log                     = $injector.get('$log');
             var formService              = $injector.get('formService');
             var translationStringService = $injector.get('translationStringService');
 
@@ -116,7 +117,9 @@ angular.module('form').directive('guacFormField', [function formField() {
                 // Append field content
                 if (field) {
                     formService.insertFieldElement(fieldContent[0],
-                        field.type, $scope);
+                        field.type, $scope)['catch'](function fieldCreationFailed() {
+                            $log.warn('Failed to retrieve field with type "' + field.type + '"');
+                    });
                 }
 
             });

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js b/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js
index 97a4f22..a0515ea 100644
--- a/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js
+++ b/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js
@@ -94,6 +94,7 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList()
             // Required services
             var activeConnectionService = $injector.get('activeConnectionService');
             var dataSourceService       = $injector.get('dataSourceService');
+            var requestService          = $injector.get('requestService');
 
             // Required types
             var GroupListItem = $injector.get('GroupListItem');
@@ -221,7 +222,7 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList()
                             });
                         });
 
-                    });
+                    }, requestService.WARN);
 
                 }
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/home/controllers/homeController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/home/controllers/homeController.js b/guacamole/src/main/webapp/app/home/controllers/homeController.js
index 150ac4e..f0e753d 100644
--- a/guacamole/src/main/webapp/app/home/controllers/homeController.js
+++ b/guacamole/src/main/webapp/app/home/controllers/homeController.js
@@ -32,6 +32,7 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
     var authenticationService  = $injector.get('authenticationService');
     var connectionGroupService = $injector.get('connectionGroupService');
     var dataSourceService      = $injector.get('dataSourceService');
+    var requestService         = $injector.get('requestService');
 
     /**
      * Map of data source identifier to the root connection group of that data
@@ -126,6 +127,6 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
     )
     .then(function rootGroupsRetrieved(rootConnectionGroups) {
         $scope.rootConnectionGroups = rootConnectionGroups;
-    });
+    }, requestService.WARN);
 
 }]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/index/controllers/indexController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/controllers/indexController.js b/guacamole/src/main/webapp/app/index/controllers/indexController.js
index c83e209..5cff962 100644
--- a/guacamole/src/main/webapp/app/index/controllers/indexController.js
+++ b/guacamole/src/main/webapp/app/index/controllers/indexController.js
@@ -137,7 +137,7 @@ angular.module('index').controller('indexController', ['$scope', '$injector',
     var checkClipboard = function checkClipboard() {
         clipboardService.getLocalClipboard().then(function clipboardRead(data) {
             $scope.$broadcast('guacClipboard', data);
-        })['catch'](angular.noop);
+        }, angular.noop);
     };
 
     // Attempt to read the clipboard if it may have changed

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/list/directives/guacUserItem.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/list/directives/guacUserItem.js b/guacamole/src/main/webapp/app/list/directives/guacUserItem.js
index 5c5d26d..6d13cec 100644
--- a/guacamole/src/main/webapp/app/list/directives/guacUserItem.js
+++ b/guacamole/src/main/webapp/app/list/directives/guacUserItem.js
@@ -77,7 +77,7 @@ angular.module('list').directive('guacUserItem', [function guacUserItem() {
                     $translate('LIST.TEXT_ANONYMOUS_USER')
                     .then(function retrieveAnonymousDisplayName(anonymousDisplayName) {
                         $scope.displayName = anonymousDisplayName;
-                    });
+                    }, angular.noop);
                 }
 
                 // For all other users, use the username verbatim

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/login/directives/login.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/login/directives/login.js b/guacamole/src/main/webapp/app/login/directives/login.js
index 51c366f..562e397 100644
--- a/guacamole/src/main/webapp/app/login/directives/login.js
+++ b/guacamole/src/main/webapp/app/login/directives/login.js
@@ -68,6 +68,7 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
         // Required services
         var $route                = $injector.get('$route');
         var authenticationService = $injector.get('authenticationService');
+        var requestService        = $injector.get('requestService');
 
         /**
          * A description of the error that occurred during login, if any.
@@ -153,7 +154,7 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
             })
 
             // Reset upon failure
-            ['catch'](function loginFailed(error) {
+            ['catch'](requestService.createErrorCallback(function loginFailed(error) {
 
                 // Clear out passwords if the credentials were rejected for any reason
                 if (error.type !== Error.Type.INSUFFICIENT_CREDENTIALS) {
@@ -178,7 +179,7 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
                     });
                 }
 
-            });
+            }));
 
         };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index 2fd8156..66e2aeb 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -38,22 +38,11 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
     var connectionService        = $injector.get('connectionService');
     var connectionGroupService   = $injector.get('connectionGroupService');
     var permissionService        = $injector.get('permissionService');
+    var requestService           = $injector.get('requestService');
     var schemaService            = $injector.get('schemaService');
     var translationStringService = $injector.get('translationStringService');
 
     /**
-     * An action to be provided along with the object sent to showStatus which
-     * closes the currently-shown status dialog.
-     */
-    var ACKNOWLEDGE_ACTION = {
-        name        : "MANAGE_CONNECTION.ACTION_ACKNOWLEDGE",
-        // Handle action
-        callback    : function acknowledgeCallback() {
-            guacNotification.showStatus(false);
-        }
-    };
-
-    /**
      * The unique identifier of the data source containing the connection being
      * edited.
      *
@@ -186,7 +175,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
     schemaService.getConnectionAttributes($scope.selectedDataSource)
     .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
-    });
+    }, requestService.WARN);
 
     // Pull connection group hierarchy
     connectionGroupService.getConnectionGroupTree(
@@ -196,7 +185,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
     )
     .then(function connectionGroupReceived(rootGroup) {
         $scope.rootGroup = rootGroup;
-    });
+    }, requestService.WARN);
     
     // Query the user's permissions for the current connection
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
@@ -226,18 +215,18 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
                )
             );
     
-    });
+    }, requestService.WARN);
    
     // Get protocol metadata
     schemaService.getProtocols($scope.selectedDataSource)
     .then(function protocolsReceived(protocols) {
         $scope.protocols = protocols;
-    });
+    }, requestService.WARN);
 
     // Get history date format
     $translate('MANAGE_CONNECTION.FORMAT_HISTORY_START').then(function historyDateFormatReceived(historyDateFormat) {
         $scope.historyDateFormat = historyDateFormat;
-    });
+    }, angular.noop);
 
     // If we are editing an existing connection, pull its data
     if (identifier) {
@@ -246,7 +235,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         connectionService.getConnection($scope.selectedDataSource, identifier)
         .then(function connectionRetrieved(connection) {
             $scope.connection = connection;
-        });
+        }, requestService.WARN);
 
         // Pull connection history
         connectionService.getConnectionHistory($scope.selectedDataSource, identifier)
@@ -258,13 +247,13 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
                $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry)); 
             });
 
-        });
+        }, requestService.WARN);
 
         // Pull connection parameters
         connectionService.getConnectionParameters($scope.selectedDataSource, identifier)
         .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
-        });
+        }, requestService.WARN);
     }
     
     // If we are cloning an existing connection, pull its data instead
@@ -277,7 +266,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
             
             // Clear the identifier field because this connection is new
             delete $scope.connection.identifier;
-        });
+        }, requestService.WARN);
 
         // Do not pull connection history
         $scope.historyEntryWrappers = [];
@@ -286,7 +275,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         connectionService.getConnectionParameters($scope.selectedDataSource, cloneSourceIdentifier)
         .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
-        });
+        }, requestService.WARN);
     }
 
     // If we are creating a new connection, populate skeleton connection data
@@ -390,17 +379,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         connectionService.saveConnection($scope.selectedDataSource, $scope.connection)
         .then(function savedConnection() {
             $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        .error(function connectionSaveFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_CONNECTION.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
     
@@ -440,17 +419,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         connectionService.deleteConnection($scope.selectedDataSource, $scope.connection)
         .then(function deletedConnection() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        .error(function connectionDeletionFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_CONNECTION.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index 6cdda80..cab4b18 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -34,21 +34,10 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
     var connectionGroupService = $injector.get('connectionGroupService');
     var guacNotification       = $injector.get('guacNotification');
     var permissionService      = $injector.get('permissionService');
+    var requestService         = $injector.get('requestService');
     var schemaService          = $injector.get('schemaService');
     
     /**
-     * An action to be provided along with the object sent to showStatus which
-     * closes the currently-shown status dialog.
-     */
-    var ACKNOWLEDGE_ACTION = {
-        name        : "MANAGE_CONNECTION_GROUP.ACTION_ACKNOWLEDGE",
-        // Handle action
-        callback    : function acknowledgeCallback() {
-            guacNotification.showStatus(false);
-        }
-    };
-
-    /**
      * The unique identifier of the data source containing the connection group
      * being edited.
      *
@@ -131,7 +120,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
     schemaService.getConnectionGroupAttributes($scope.selectedDataSource)
     .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
-    });
+    }, requestService.WARN);
 
     // Query the user's permissions for the current connection group
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
@@ -152,7 +141,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
               ||  PermissionSet.hasConnectionGroupPermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier)
            );
     
-    });
+    }, requestService.WARN);
 
 
     // Pull connection group hierarchy
@@ -163,14 +152,14 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
     )
     .then(function connectionGroupReceived(rootGroup) {
         $scope.rootGroup = rootGroup;
-    });
+    }, requestService.WARN);
 
     // If we are editing an existing connection group, pull its data
     if (identifier) {
         connectionGroupService.getConnectionGroup($scope.selectedDataSource, identifier)
         .then(function connectionGroupReceived(connectionGroup) {
             $scope.connectionGroup = connectionGroup;
-        });
+        }, requestService.WARN);
     }
 
     // If we are creating a new connection group, populate skeleton connection group data
@@ -232,17 +221,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
         connectionGroupService.saveConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
         .then(function savedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        ['catch'](function connectionGroupSaveFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_CONNECTION_GROUP.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
     
@@ -282,17 +261,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
         connectionGroupService.deleteConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
         .then(function deletedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        ['catch'](function connectionGroupDeletionFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_CONNECTION_GROUP.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 1adead8..886f54c 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -34,23 +34,12 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     var connectionService        = $injector.get('connectionService');
     var guacNotification         = $injector.get('guacNotification');
     var permissionService        = $injector.get('permissionService');
+    var requestService           = $injector.get('requestService');
     var schemaService            = $injector.get('schemaService');
     var sharingProfileService    = $injector.get('sharingProfileService');
     var translationStringService = $injector.get('translationStringService');
 
     /**
-     * An action which can be provided along with the object sent to showStatus
-     * to allow the user to acknowledge (and close) the currently-shown status
-     * dialog.
-     */
-    var ACKNOWLEDGE_ACTION = {
-        name        : "MANAGE_SHARING_PROFILE.ACTION_ACKNOWLEDGE",
-        callback    : function acknowledgeCallback() {
-            guacNotification.showStatus(false);
-        }
-    };
-
-    /**
      * An action to be provided along with the object sent to showStatus which
      * closes the currently-shown status dialog, effectively canceling the
      * operation which was pending user confirmation.
@@ -172,7 +161,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     schemaService.getSharingProfileAttributes($scope.selectedDataSource)
     .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
-    });
+    }, requestService.WARN);
 
     // Query the user's permissions for the current sharing profile
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
@@ -208,13 +197,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
                )
             );
 
-    });
+    }, requestService.WARN);
 
     // Get protocol metadata
     schemaService.getProtocols($scope.selectedDataSource)
     .then(function protocolsReceived(protocols) {
         $scope.protocols = protocols;
-    });
+    }, requestService.WARN);
 
     // If we are editing an existing sharing profile, pull its data
     if (identifier) {
@@ -223,13 +212,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         sharingProfileService.getSharingProfile($scope.selectedDataSource, identifier)
         .then(function sharingProfileRetrieved(sharingProfile) {
             $scope.sharingProfile = sharingProfile;
-        });
+        }, requestService.WARN);
 
         // Pull sharing profile parameters
         sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, identifier)
         .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
-        });
+        }, requestService.WARN);
 
     }
 
@@ -246,13 +235,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
             // Clear the identifier field because this sharing profile is new
             delete $scope.sharingProfile.identifier;
 
-        });
+        }, requestService.WARN);
 
         // Pull sharing profile parameters from cloned sharing profile
         sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, cloneSourceIdentifier)
         .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
-        });
+        }, requestService.WARN);
 
     }
 
@@ -276,7 +265,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         connectionService.getConnection($scope.selectedDataSource, identifier)
         .then(function connectionRetrieved(connection) {
             $scope.primaryConnection = connection;
-        });
+        }, requestService.WARN);
 
     });
 
@@ -353,17 +342,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
         .then(function savedSharingProfile() {
             $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        ['catch'](function sharingProfileSaveFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
 
@@ -391,17 +370,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
         .then(function deletedSharingProfile() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        })
-
-        // Notify of any errors
-        ['catch'](function sharingProfileDeletionFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 76a8376..d0b6be4 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -39,6 +39,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
     var dataSourceService        = $injector.get('dataSourceService');
     var guacNotification         = $injector.get('guacNotification');
     var permissionService        = $injector.get('permissionService');
+    var requestService           = $injector.get('requestService');
     var schemaService            = $injector.get('schemaService');
     var translationStringService = $injector.get('translationStringService');
     var userService              = $injector.get('userService');
@@ -531,7 +532,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
     // Pull user attribute schema
     schemaService.getUserAttributes(selectedDataSource).then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
-    });
+    }, requestService.WARN);
 
     // Pull user data and permissions if we are editing an existing user
     if (username) {
@@ -550,7 +551,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
                     'username' : username
                 });
 
-        });
+        }, requestService.WARN);
 
         // The current user will be associated with username of the existing
         // user in the retrieved permission set
@@ -562,9 +563,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         })
 
         // If permissions cannot be retrieved, use empty permissions
-        ['catch'](function permissionRetrievalFailed() {
+        ['catch'](requestService.createErrorCallback(function permissionRetrievalFailed() {
             $scope.permissionFlags = new PermissionFlagSet();
-        });
+        }));
     }
 
     // If we are cloning an existing user, pull his/her data instead
@@ -577,7 +578,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
             $scope.users = {};
             $scope.user  = users[selectedDataSource];
 
-        });
+        }, requestService.WARN);
 
         // The current user will be associated with cloneSourceUsername in the
         // retrieved permission set
@@ -591,9 +592,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         })
 
         // If permissions cannot be retrieved, use empty permissions
-        ['catch'](function permissionRetrievalFailed() {
+        ['catch'](requestService.createErrorCallback(function permissionRetrievalFailed() {
             $scope.permissionFlags = new PermissionFlagSet();
-        });
+        }));
     }
 
     // Use skeleton data if we are creating a new user
@@ -676,7 +677,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
             $scope.rootGroups[dataSource] = GroupListItem.fromConnectionGroup(dataSource, rootGroup);
         });
 
-    });
+    }, requestService.WARN);
     
     // Query the user's permissions for the current user
     dataSourceService.apply(
@@ -686,7 +687,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
     )
     .then(function permissionsReceived(permissions) {
         $scope.permissions = permissions;
-    });
+    }, requestService.WARN);
 
     // Update default expanded state whenever connection groups and associated
     // permissions change
@@ -1140,30 +1141,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
             permissionService.patchPermissions(selectedDataSource, $scope.user.username, permissionsAdded, permissionsRemoved)
             .then(function patchedUserPermissions() {
                 $location.url('/settings/users');
-            })
-
-            // Notify of any errors
-            ['catch'](function userPermissionsPatchFailed(error) {
-                guacNotification.showStatus({
-                    'className'  : 'error',
-                    'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR',
-                    'text'       : error.translatableMessage,
-                    'values'     : error.translationValues,
-                    'actions'    : [ ACKNOWLEDGE_ACTION ]
-                });
-            });
+            }, requestService.SHOW_NOTIFICATION);
 
-        })
-
-        // Notify of any errors
-        .error(function userSaveFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
     
@@ -1203,17 +1183,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         userService.deleteUser(selectedDataSource, $scope.user)
         .then(function deletedUser() {
             $location.path('/settings/users');
-        })
-
-        // Notify of any errors
-        ['catch'](function userDeletionFailed(error) {
-            guacNotification.showStatus({
-                'className'  : 'error',
-                'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR',
-                'text'       : error.translatableMessage,
-                'actions'    : [ ACKNOWLEDGE_ACTION ]
-            });
-        });
+        }, requestService.SHOW_NOTIFICATION);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
index 13de858..492a867 100644
--- a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
+++ b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
@@ -50,6 +50,7 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu()
             var $location             = $injector.get('$location');
             var $route                = $injector.get('$route');
             var authenticationService = $injector.get('authenticationService');
+            var requestService        = $injector.get('requestService');
             var userService           = $injector.get('userService');
             var userPageService       = $injector.get('userPageService');
 
@@ -110,7 +111,7 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu()
                 var email = user.attributes[User.Attributes.EMAIL_ADDRESS];
                 $scope.userURL = email ? 'mailto:' + email : null;
 
-            });
+            }, requestService.WARN);
 
             /**
              * The available main pages for the current user.
@@ -141,7 +142,9 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu()
              * after logout completes.
              */
             $scope.logout = function logout() {
-                authenticationService.logout()['finally'](function logoutComplete() {
+                authenticationService.logout()
+                ['catch'](requestService.IGNORE)
+                ['finally'](function logoutComplete() {
                     if ($location.path() !== '/')
                         $location.url('/');
                     else

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/navigation/services/userPageService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/navigation/services/userPageService.js b/guacamole/src/main/webapp/app/navigation/services/userPageService.js
index 24d340b..4d1e612 100644
--- a/guacamole/src/main/webapp/app/navigation/services/userPageService.js
+++ b/guacamole/src/main/webapp/app/navigation/services/userPageService.js
@@ -35,6 +35,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
     var connectionGroupService   = $injector.get('connectionGroupService');
     var dataSourceService        = $injector.get('dataSourceService');
     var permissionService        = $injector.get('permissionService');
+    var requestService           = $injector.get('requestService');
     var translationStringService = $injector.get('translationStringService');
     
     var service = {};
@@ -142,7 +143,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
 
     /**
      * Returns a promise which resolves with an appropriate home page for the
-     * current user.
+     * current user. The promise will not be rejected.
      *
      * @returns {Promise.<Page>}
      *     A promise which resolves with the user's default home page.
@@ -169,7 +170,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
         })
         .then(function rootConnectionGroupsPermissionsRetrieved(data) {
             deferred.resolve(generateHomePage(data.rootGroups,data.permissionsSets));
-        });
+        }, requestService.WARN);
 
         return deferred.promise;
 
@@ -317,7 +318,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
     /**
      * Returns a promise which resolves to an array of all settings pages that
      * the current user can visit. This can include any of the various manage
-     * pages.
+     * pages. The promise will not be rejected.
      *
      * @returns {Promise.<Page[]>} 
      *     A promise which resolves to an array of all settings pages that the
@@ -337,7 +338,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
         // Resolve promise using settings pages derived from permissions
         .then(function permissionsRetrieved(permissions) {
             deferred.resolve(generateSettingsPages(permissions));
-        });
+        }, requestService.WARN);
         
         return deferred.promise;
 
@@ -387,7 +388,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
      * Returns a promise which resolves to an array of all main pages that the
      * current user can visit. This can include the home page, manage pages,
      * etc. In the case that there are no applicable pages of this sort, it may
-     * return a client page.
+     * return a client page. The promise will not be rejected.
      *
      * @returns {Promise.<Page[]>} 
      *     A promise which resolves to an array of all main pages that the
@@ -418,7 +419,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
         .then(function rootConnectionGroupsRetrieved(retrievedRootGroups) {
             rootGroups = retrievedRootGroups;
             resolveMainPages();
-        });
+        }, requestService.WARN);
 
         // Retrieve current permissions
         dataSourceService.apply(
@@ -431,7 +432,7 @@ angular.module('navigation').factory('userPageService', ['$injector',
         .then(function permissionsRetrieved(retrievedPermissions) {
             permissions = retrievedPermissions;
             resolveMainPages();
-        });
+        }, requestService.WARN);
         
         return deferred.promise;
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/dataSourceService.js b/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
index 783aa10..6405394 100644
--- a/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
+++ b/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
@@ -27,7 +27,8 @@ angular.module('rest').factory('dataSourceService', ['$injector',
     var Error = $injector.get('Error');
 
     // Required services
-    var $q = $injector.get('$q');
+    var $q             = $injector.get('$q');
+    var requestService = $injector.get('requestService');
 
     // Service containing all caches
     var service = {};
@@ -92,7 +93,7 @@ angular.module('rest').factory('dataSourceService', ['$injector',
             },
 
             // Fail on any errors (except "NOT FOUND")
-            function immediateRequestFailed(error) {
+            requestService.createErrorCallback(function immediateRequestFailed(error) {
 
                 if (error.type === Error.Type.NOT_FOUND)
                     deferredRequest.resolve();
@@ -101,7 +102,7 @@ angular.module('rest').factory('dataSourceService', ['$injector',
                 else
                     deferredRequest.reject(error);
 
-            });
+            }));
 
         });
 
@@ -111,9 +112,9 @@ angular.module('rest').factory('dataSourceService', ['$injector',
         },
 
         // Reject if at least one request fails
-        function requestFailed(response) {
-            deferred.reject(response);
-        });
+        requestService.createErrorCallback(function requestFailed(error) {
+            deferred.reject(error);
+        }));
 
         return deferred.promise;
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
index 36da4ad..c184a13 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
@@ -44,6 +44,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
             var $translate     = $injector.get('$translate');
             var csvService     = $injector.get('csvService');
             var historyService = $injector.get('historyService');
+            var requestService = $injector.get('requestService');
 
             /**
              * The identifier of the currently-selected data source.
@@ -95,7 +96,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
                 // Store received date format
                 $scope.dateFormat = retrievedDateFormat;
 
-            });
+            }, angular.noop);
             
             /**
              * Returns true if the connection history records have been loaded,
@@ -177,7 +178,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
                        $scope.historyEntryWrappers.push(new ConnectionHistoryEntryWrapper(historyEntry)); 
                     });
 
-                });
+                }, requestService.WARN);
 
             };
             
@@ -227,7 +228,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
                     // Save the result
                     saveAs(csvService.toBlob(records), translations['SETTINGS_CONNECTION_HISTORY.FILENAME_HISTORY_CSV']);
 
-                });
+                }, angular.noop);
 
             };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
index dd9f5c8..2f7fafb 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
@@ -46,6 +46,7 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
             var dataSourceService      = $injector.get('dataSourceService');
             var guacNotification       = $injector.get('guacNotification');
             var permissionService      = $injector.get('permissionService');
+            var requestService         = $injector.get('requestService');
 
             /**
              * The identifier of the current user.
@@ -55,18 +56,6 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
             var currentUsername = authenticationService.getCurrentUsername();
 
             /**
-             * An action to be provided along with the object sent to
-             * showStatus which closes the currently-shown status dialog.
-             */
-            var ACKNOWLEDGE_ACTION = {
-                name        : "SETTINGS_CONNECTIONS.ACTION_ACKNOWLEDGE",
-                // Handle action
-                callback    : function acknowledgeCallback() {
-                    guacNotification.showStatus(false);
-                }
-            };
-
-            /**
              * The identifier of the currently-selected data source.
              *
              * @type String
@@ -426,9 +415,9 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
                 )
                 .then(function connectionGroupsReceived(rootGroups) {
                     $scope.rootGroups = rootGroups;
-                });
+                }, requestService.WARN);
 
-            }); // end retrieve permissions
+            }, requestService.WARN); // end retrieve permissions
 
         }]
     };

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
index 12039b1..6cfd440 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
@@ -42,6 +42,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
             var languageService       = $injector.get('languageService');
             var permissionService     = $injector.get('permissionService');
             var preferenceService     = $injector.get('preferenceService');
+            var requestService        = $injector.get('requestService');
             var userService           = $injector.get('userService');
 
             /**
@@ -164,17 +165,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                         },
                         actions : [ ACKNOWLEDGE_ACTION ]
                     });
-                })
-                
-                // Notify of any errors
-                ['catch'](function passwordUpdateFailed(error) {
-                    guacNotification.showStatus({
-                        className  : 'error',
-                        title      : 'SETTINGS_PREFERENCES.DIALOG_HEADER_ERROR',
-                        text       : error.translatableMessage,
-                        actions    : [ ACKNOWLEDGE_ACTION ]
-                    });
-                });
+                }, requestService.SHOW_NOTIFICATION);
                 
             };
 
@@ -186,8 +177,8 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                         key: key,
                         value: languages[key]
                     };
-                })
-            });
+                });
+            }, requestService.WARN);
 
             // Retrieve current permissions
             permissionService.getEffectivePermissions(dataSource, username)
@@ -198,9 +189,9 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                         PermissionSet.ObjectPermissionType.UPDATE, username);
                         
             })
-            ['catch'](function permissionsFailed(error) {
+            ['catch'](requestService.createErrorCallback(function permissionsFailed(error) {
                 $scope.canChangePassword = false;
-            });
+            }));
 
             /**
              * Returns whether critical data has completed being loaded.

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
index a8c13c4..8563d52 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
@@ -47,6 +47,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
             var connectionGroupService  = $injector.get('connectionGroupService');
             var dataSourceService       = $injector.get('dataSourceService');
             var guacNotification        = $injector.get('guacNotification');
+            var requestService          = $injector.get('requestService');
 
             /**
              * The identifiers of all data sources accessible by the current
@@ -219,7 +220,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
                 // Attempt to produce wrapped list of active connections
                 wrapAllActiveConnections();
 
-            });
+            }, requestService.WARN);
             
             // Query active sessions
             dataSourceService.apply(
@@ -234,7 +235,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
                 // Attempt to produce wrapped list of active connections
                 wrapAllActiveConnections();
 
-            });
+            }, requestService.WARN);
 
             // Get session date format
             $translate('SETTINGS_SESSIONS.FORMAT_STARTDATE').then(function sessionDateFormatReceived(retrievedSessionDateFormat) {
@@ -245,7 +246,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
                 // Attempt to produce wrapped list of active connections
                 wrapAllActiveConnections();
 
-            });
+            }, angular.noop);
 
             /**
              * Returns whether critical data has completed being loaded.
@@ -262,18 +263,6 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
              * An action to be provided along with the object sent to
              * showStatus which closes the currently-shown status dialog.
              */
-            var ACKNOWLEDGE_ACTION = {
-                name        : "SETTINGS_SESSIONS.ACTION_ACKNOWLEDGE",
-                // Handle action
-                callback    : function acknowledgeCallback() {
-                    guacNotification.showStatus(false);
-                }
-            };
-
-            /**
-             * An action to be provided along with the object sent to
-             * showStatus which closes the currently-shown status dialog.
-             */
             var CANCEL_ACTION = {
                 name        : "SETTINGS_SESSIONS.ACTION_CANCEL",
                 // Handle action
@@ -327,17 +316,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
                     // Clear selection
                     allSelectedWrappers = {};
 
-                },
-
-                // Notify of any errors
-                function activeConnectionDeletionFailed(error) {
-                    guacNotification.showStatus({
-                        'className'  : 'error',
-                        'title'      : 'SETTINGS_SESSIONS.DIALOG_HEADER_ERROR',
-                        'text'       : error.translatableMessage,
-                        'actions'    : [ ACKNOWLEDGE_ACTION ]
-                    });
-                });
+                }, requestService.SHOW_NOTIFICATION);
 
             }; 
             

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/266b445c/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
index c143399..870a862 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsUsers.js
@@ -43,26 +43,14 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
             var $translate             = $injector.get('$translate');
             var authenticationService  = $injector.get('authenticationService');
             var dataSourceService      = $injector.get('dataSourceService');
-            var guacNotification       = $injector.get('guacNotification');
             var permissionService      = $injector.get('permissionService');
+            var requestService         = $injector.get('requestService');
             var userService            = $injector.get('userService');
 
             // Identifier of the current user
             var currentUsername = authenticationService.getCurrentUsername();
 
             /**
-             * An action to be provided along with the object sent to
-             * showStatus which closes the currently-shown status dialog.
-             */
-            var ACKNOWLEDGE_ACTION = {
-                name        : "SETTINGS_USERS.ACTION_ACKNOWLEDGE",
-                // Handle action
-                callback    : function acknowledgeCallback() {
-                    guacNotification.showStatus(false);
-                }
-            };
-
-            /**
              * The identifiers of all data sources accessible by the current
              * user.
              *
@@ -129,7 +117,7 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
                 // Store received date format
                 $scope.dateFormat = retrievedDateFormat;
 
-            });
+            }, angular.noop);
 
             /**
              * Returns whether critical data has completed being loaded.
@@ -287,9 +275,9 @@ angular.module('settings').directive('guacSettingsUsers', [function guacSettings
                         });
                     });
 
-                });
+                }, requestService.WARN);
 
-            });
+            }, requestService.WARN);
             
         }]
     };