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:43 UTC

[01/19] guacamole-client git commit: GUACAMOLE-526: Maintain full correct chain of promises for clipboard read attempts, including the "finally" used for cleanup. The "finally" handler creates a new promise with a potentially unhandled rejection otherwis

Repository: guacamole-client
Updated Branches:
  refs/heads/master 9a2e0c608 -> 9d09f0bb0


GUACAMOLE-526: Maintain full correct chain of promises for clipboard read attempts, including the "finally" used for cleanup. The "finally" handler creates a new promise with a potentially unhandled rejection otherwise.

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

Branch: refs/heads/master
Commit: 01e19c19dcd9882128f14b2c6286dea3a62878c3
Parents: 670ec39
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 14:43:54 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:42:52 2018 -0700

----------------------------------------------------------------------
 .../app/clipboard/services/clipboardService.js  | 125 +++++++++----------
 1 file changed, 62 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/01e19c19/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
index 920006e..9000c18 100644
--- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
+++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js
@@ -415,80 +415,78 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
 
         var deferred = $q.defer();
 
-        // Mark read attempt as in progress
-        pendingRead = deferred.promise;
-
-        // Wait for the next event queue run before attempting to read
-        // clipboard data (in case the copy/cut has not yet completed)
-        $window.setTimeout(function deferredClipboardRead() {
-
-            // Track the originally-focused element prior to changing focus
-            var originalElement = document.activeElement;
-            pushSelection();
+        // Track the originally-focused element prior to changing focus
+        var originalElement = document.activeElement;
 
-            /**
-             * Attempts to paste the clipboard contents into the
-             * currently-focused element. The promise related to the current
-             * attempt to read the clipboard will be resolved or rejected
-             * depending on whether the attempt to paste succeeds.
-             */
-            var performPaste = function performPaste() {
-
-                // Attempt paste local clipboard into clipboard DOM element
-                if (document.execCommand('paste')) {
-
-                    // If the pasted data is a single image, resolve with a blob
-                    // containing that image
-                    var currentImage = service.getImageContent(clipboardContent);
-                    if (currentImage) {
-
-                        // Convert the image's data URL into a blob
-                        var blob = service.parseDataURL(currentImage);
-                        if (blob) {
-                            deferred.resolve(new ClipboardData({
-                                type : blob.type,
-                                data : blob
-                            }));
-                        }
-
-                        // Reject if conversion fails
-                        else
-                            deferred.reject();
-
-                    } // end if clipboard is an image
-
-                    // Otherwise, assume the clipboard contains plain text
-                    else
+        /**
+         * Attempts to paste the clipboard contents into the
+         * currently-focused element. The promise related to the current
+         * attempt to read the clipboard will be resolved or rejected
+         * depending on whether the attempt to paste succeeds.
+         */
+        var performPaste = function performPaste() {
+
+            // Attempt paste local clipboard into clipboard DOM element
+            if (document.execCommand('paste')) {
+
+                // If the pasted data is a single image, resolve with a blob
+                // containing that image
+                var currentImage = service.getImageContent(clipboardContent);
+                if (currentImage) {
+
+                    // Convert the image's data URL into a blob
+                    var blob = service.parseDataURL(currentImage);
+                    if (blob) {
                         deferred.resolve(new ClipboardData({
-                            type : 'text/plain',
-                            data : clipboardContent.value
+                            type : blob.type,
+                            data : blob
                         }));
+                    }
 
-                }
+                    // Reject if conversion fails
+                    else
+                        deferred.reject();
+
+                } // end if clipboard is an image
 
-                // Otherwise, reading from the clipboard has failed
+                // Otherwise, assume the clipboard contains plain text
                 else
-                    deferred.reject();
+                    deferred.resolve(new ClipboardData({
+                        type : 'text/plain',
+                        data : clipboardContent.value
+                    }));
 
-            };
+            }
 
-            // Clean up event listener and selection once the paste attempt has
-            // completed
-            deferred.promise['finally'](function cleanupReadAttempt() {
+            // Otherwise, reading from the clipboard has failed
+            else
+                deferred.reject();
+
+        };
+
+        // Mark read attempt as in progress, cleaning up event listener and
+        // selection once the paste attempt has completed
+        pendingRead = deferred.promise['finally'](function cleanupReadAttempt() {
+
+            // Do not use future changes in focus
+            clipboardContent.removeEventListener('focus', performPaste);
+
+            // Unfocus the clipboard DOM event to avoid mobile keyboard opening,
+            // restoring whichever element was originally focused
+            clipboardContent.blur();
+            originalElement.focus();
+            popSelection();
 
-                // Do not use future changes in focus
-                clipboardContent.removeEventListener('focus', performPaste);
+            // No read is pending any longer
+            pendingRead = null;
 
-                // Unfocus the clipboard DOM event to avoid mobile keyboard opening,
-                // restoring whichever element was originally focused
-                clipboardContent.blur();
-                originalElement.focus();
-                popSelection();
+        });
 
-                // No read is pending any longer
-                pendingRead = null;
+        // Wait for the next event queue run before attempting to read
+        // clipboard data (in case the copy/cut has not yet completed)
+        $window.setTimeout(function deferredClipboardRead() {
 
-            });
+            pushSelection();
 
             // Ensure clipboard element is blurred (and that the "focus" event
             // will fire)
@@ -506,7 +504,8 @@ angular.module('clipboard').factory('clipboardService', ['$injector',
 
         }, CLIPBOARD_READ_DELAY);
 
-        return deferred.promise;
+        return pendingRead;
+
     };
 
     return service;


[04/19] guacamole-client git commit: GUACAMOLE-526: Explicitly fail routing if attempting to update the auth token fails.

Posted by vn...@apache.org.
GUACAMOLE-526: Explicitly fail routing if attempting to update the auth token fails.

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

Branch: refs/heads/master
Commit: bba01bdbc45c74d4b8aafc59223bd16cf2bf5392
Parents: 6cd0705
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 15:27:18 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:51:46 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/index/config/indexRouteConfig.js | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/bba01bdb/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
index d662266..47bc48e 100644
--- a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
+++ b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
@@ -102,6 +102,10 @@ angular.module('index').config(['$routeProvider', '$locationProvider',
                 route.resolve();
             });
 
+        })
+
+        ['catch'](function tokenUpdateFailed() {
+            route.reject();
         });
 
         // Return promise that will resolve only if the requested page is the


[12/19] guacamole-client git commit: GUACAMOLE-526: Add convenience function for displaying modal notifications for REST errors.

Posted by vn...@apache.org.
GUACAMOLE-526: Add convenience function for displaying modal notifications for REST errors.

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

Branch: refs/heads/master
Commit: 1e5e9b607b56e8cf0fd15b9b58337baa6c0652aa
Parents: cc6ade4
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 21:20:05 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 21:20:05 2018 -0700

----------------------------------------------------------------------
 .../notification/services/guacNotification.js   | 35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/1e5e9b60/guacamole/src/main/webapp/app/notification/services/guacNotification.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/notification/services/guacNotification.js b/guacamole/src/main/webapp/app/notification/services/guacNotification.js
index c3d4a2b..a1b8d10 100644
--- a/guacamole/src/main/webapp/app/notification/services/guacNotification.js
+++ b/guacamole/src/main/webapp/app/notification/services/guacNotification.js
@@ -38,6 +38,19 @@ angular.module('notification').factory('guacNotification', ['$injector',
     var storedStatus = sessionStorageFactory.create(false);
 
     /**
+     * An action to be provided along with the object sent to showStatus which
+     * closes the currently-shown status dialog.
+     *
+     * @type NotificationAction
+     */
+    service.ACKNOWLEDGE_ACTION = {
+        name        : 'APP.ACTION_ACKNOWLEDGE',
+        callback    : function acknowledgeCallback() {
+            service.showStatus(false);
+        }
+    };
+
+    /**
      * Retrieves the current status notification, which may simply be false if
      * no status is currently shown.
      * 
@@ -79,6 +92,28 @@ angular.module('notification').factory('guacNotification', ['$injector',
             storedStatus(status);
     };
 
+    /**
+     * Shows the given REST error response as a modal status. If a status
+     * notification is already currently shown, this function will have no
+     * effect.
+     *
+     * @param {Error} error
+     *     The error object returned from the failed REST request.
+     *
+     * @example
+     *
+     * someService.updateObject(object)
+     * ['catch'](guacNotification.showRequestError);
+     */
+    service.showRequestError = function showRequestError(error) {
+        service.showStatus({
+            className  : 'error',
+            title      : 'APP.DIALOG_HEADER_ERROR',
+            text       : error.translatableMessage,
+            actions    : [ service.ACKNOWLEDGE_ACTION ]
+        });
+    };
+
     // Hide status upon navigation
     $rootScope.$on('$routeChangeSuccess', function() {
         service.showStatus(false);


[10/19] guacamole-client git commit: GUACAMOLE-526: Add convenience function for generating promise callbacks which handle only REST errors.

Posted by vn...@apache.org.
GUACAMOLE-526: Add convenience function for generating promise callbacks which handle only REST errors.

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

Branch: refs/heads/master
Commit: c30b7b0d8030e6b91f102f12df160c63a72b76c5
Parents: 8c9735d
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 21:11:51 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 21:11:51 2018 -0700

----------------------------------------------------------------------
 .../webapp/app/rest/services/requestService.js  | 31 +++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/c30b7b0d/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index f17ce25..b2f709b 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -26,6 +26,7 @@ angular.module('rest').factory('requestService', ['$injector',
 
     // Required services
     var $http = $injector.get('$http');
+    var $log  = $injector.get('$log');
 
     // Required types
     var Error = $injector.get('Error');
@@ -62,6 +63,34 @@ angular.module('rest').factory('requestService', ['$injector',
         );
     };
 
-    return service;
+    /**
+     * Creates a promise error callback which invokes the given callback only
+     * if the promise was rejected with a REST @link{Error} object. If the
+     * promise is rejected without an @link{Error} object, such as when a
+     * JavaScript error occurs within a callback earlier in the promise chain,
+     * the rejection is logged without invoking the given callback.
+     *
+     * @param {Function} callback
+     *     The callback to invoke if the promise is rejected with an
+     *     @link{Error} object.
+     *
+     * @returns {Function}
+     *     A function which can be provided as the error callback for a
+     *     promise.
+     */
+    service.createErrorCallback = function createErrorCallback(callback) {
+        return (function generatedErrorCallback(error) {
+
+            // Invoke given callback ONLY if due to a legitimate REST error
+            if (error instanceof Error)
+                return callback(error);
+
+            // Log all other errors
+            $log.error(error);
+
+        });
+    };
+
+   return service;
 
 }]);


[02/19] guacamole-client git commit: GUACAMOLE-526: Ignore failure to read/write clipboard.

Posted by vn...@apache.org.
GUACAMOLE-526: Ignore failure to read/write clipboard.

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

Branch: refs/heads/master
Commit: 670ec390b5f33644d854d8bb98e9cff00db381db
Parents: 9a2e0c6
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 14:42:18 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:42:52 2018 -0700

----------------------------------------------------------------------
 .../src/main/webapp/app/client/controllers/clientController.js | 6 +++---
 .../src/main/webapp/app/index/controllers/indexController.js   | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/670ec390/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 8a2f935..e89f241 100644
--- a/guacamole/src/main/webapp/app/client/controllers/clientController.js
+++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js
@@ -447,7 +447,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
 
         // Sync local clipboard as long as the menu is not open
         if (!$scope.menu.shown)
-            clipboardService.setLocalClipboard(data);
+            clipboardService.setLocalClipboard(data)['catch'](angular.noop);
 
         // Associate new clipboard data with any currently-pressed key
         for (var keysym in keysCurrentlyPressed)
@@ -576,7 +576,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
         // key was pressed (if any) as long as the menu is not open
         var clipboardData = clipboardDataFromKey[keysym];
         if (clipboardData && !$scope.menu.shown)
-            clipboardService.setLocalClipboard(clipboardData);
+            clipboardService.setLocalClipboard(clipboardData)['catch'](angular.noop);
 
         // Deal with substitute key presses
         if (substituteKeysPressed[keysym]) {
@@ -714,7 +714,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);
 
             // Hide status notification
             guacNotification.showStatus(false);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/670ec390/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 ed14233..c83e209 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);
     };
 
     // Attempt to read the clipboard if it may have changed


[17/19] guacamole-client git commit: GUACAMOLE-526: Remove debug console.log() from toArrayFilter().

Posted by vn...@apache.org.
GUACAMOLE-526: Remove debug console.log() from toArrayFilter().

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

Branch: refs/heads/master
Commit: 2ff980dedebd51e0a8f966f25012cf03563ec8b4
Parents: f8bd8d8
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 27 00:05:09 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Fri Apr 27 00:05:09 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/index/filters/arrayFilter.js | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/2ff980de/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/filters/arrayFilter.js b/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
index f0429c8..d3a5df2 100644
--- a/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
+++ b/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
@@ -25,9 +25,6 @@ angular.module('index').filter('toArray', [function toArrayFactory() {
 
     return function toArrayFiter(input) {
 
-
-        console.log(input)
-
         // If no object is available, just return an empty array
         if (!input) {
             return [];


[05/19] guacamole-client git commit: GUACAMOLE-526: Remove unused (and wrong!) getAllActiveConnections() function. Remove now-unnecessary injection of $q.

Posted by vn...@apache.org.
GUACAMOLE-526: Remove unused (and wrong!) getAllActiveConnections() function. Remove now-unnecessary injection of $q.

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

Branch: refs/heads/master
Commit: 73eb25f3118d36d4b80f5ac58a01b15b77980e00
Parents: bba01bd
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 15:30:58 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:51:46 2018 -0700

----------------------------------------------------------------------
 .../rest/services/activeConnectionService.js    | 63 --------------------
 1 file changed, 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/73eb25f3/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
index b548c86..5354bc1 100644
--- a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
@@ -25,7 +25,6 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
 
     // Required services
     var requestService        = $injector.get('requestService');
-    var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
 
     var service = {};
@@ -67,68 +66,6 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
     };
 
     /**
-     * Returns a promise which resolves with all active connections accessible
-     * by the current user, as a map of @link{ActiveConnection} maps, as would
-     * be returned by getActiveConnections(), grouped by the identifier of
-     * their corresponding data source. All given data sources are queried. If
-     * an error occurs while retrieving any ActiveConnection map, the promise
-     * will be rejected.
-     *
-     * @param {String[]} dataSources
-     *     The unique identifier of the data sources containing the active
-     *     connections to be retrieved. These identifiers correspond to
-     *     AuthenticationProviders within the Guacamole web application.
-     *
-     * @param {String[]} [permissionTypes]
-     *     The set of permissions to filter with. A user must have one or more
-     *     of these permissions for an active connection to appear in the
-     *     result.  If null, no filtering will be performed. Valid values are
-     *     listed within PermissionSet.ObjectType.
-     *
-     * @returns {Promise.<Object.<String, Object.<String, ActiveConnection>>>}
-     *     A promise which resolves with all active connections available to
-     *     the current user, as a map of ActiveConnection maps, as would be
-     *     returned by getActiveConnections(), grouped by the identifier of
-     *     their corresponding data source.
-     */
-    service.getAllActiveConnections = function getAllActiveConnections(dataSources, permissionTypes) {
-
-        var deferred = $q.defer();
-
-        var activeConnectionRequests = [];
-        var activeConnectionMaps = {};
-
-        // Retrieve all active connections from all data sources
-        angular.forEach(dataSources, function retrieveActiveConnections(dataSource) {
-            activeConnectionRequests.push(
-                service.getActiveConnections(dataSource, permissionTypes)
-                .then(function activeConnectionsRetrieved(activeConnections) {
-                    activeConnectionMaps[dataSource] = activeConnections;
-                })
-            );
-        });
-
-        // Resolve when all requests are completed
-        $q.all(activeConnectionRequests)
-        .then(
-
-            // All requests completed successfully
-            function allActiveConnectionsRetrieved() {
-                deferred.resolve(userArrays);
-            },
-
-            // At least one request failed
-            function activeConnectionRetrievalFailed(e) {
-                deferred.reject(e);
-            }
-
-        );
-
-        return deferred.promise;
-
-    };
-
-    /**
      * Makes a request to the REST API to delete the active connections having
      * the given identifiers, effectively disconnecting them, returning a
      * promise that can be used for processing the results of the call.


[06/19] guacamole-client git commit: GUACAMOLE-526: Remove unused injections of $q.

Posted by vn...@apache.org.
GUACAMOLE-526: Remove unused injections of $q.

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

Branch: refs/heads/master
Commit: 6cd07052d8adcca16dc7762aaf54a8a9040016f7
Parents: 5be3036
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 15:26:22 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:51:46 2018 -0700

----------------------------------------------------------------------
 .../src/main/webapp/app/rest/services/connectionGroupService.js     | 1 -
 guacamole/src/main/webapp/app/rest/services/permissionService.js    | 1 -
 guacamole/src/main/webapp/app/rest/services/userService.js          | 1 -
 3 files changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6cd07052/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
index b7e78e3..c6d68be 100644
--- a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
+++ b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
@@ -25,7 +25,6 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
 
     // Required services
     var requestService        = $injector.get('requestService');
-    var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
     

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6cd07052/guacamole/src/main/webapp/app/rest/services/permissionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js
index ec0a0d5..6d3dfdf 100644
--- a/guacamole/src/main/webapp/app/rest/services/permissionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/permissionService.js
@@ -25,7 +25,6 @@ angular.module('rest').factory('permissionService', ['$injector',
 
     // Required services
     var requestService        = $injector.get('requestService');
-    var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
     

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/6cd07052/guacamole/src/main/webapp/app/rest/services/userService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js
index bbf5fcf..f05ab31 100644
--- a/guacamole/src/main/webapp/app/rest/services/userService.js
+++ b/guacamole/src/main/webapp/app/rest/services/userService.js
@@ -25,7 +25,6 @@ angular.module('rest').factory('userService', ['$injector',
 
     // Required services
     var requestService        = $injector.get('requestService');
-    var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
 


[07/19] guacamole-client git commit: GUACAMOLE-526: Ignore failure to load OSK layout.

Posted by vn...@apache.org.
GUACAMOLE-526: Ignore failure to load OSK layout.

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

Branch: refs/heads/master
Commit: f6f66eec0a9b503b2cb594d6d226cc1ade9dc15c
Parents: 73eb25f
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 19:03:53 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 19:03:53 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/osk/directives/guacOsk.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f6f66eec/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
index 968e86e..2236ac8 100644
--- a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
+++ b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
@@ -113,7 +113,7 @@ angular.module('osk').directive('guacOsk', [function guacOsk() {
                             $rootScope.$broadcast('guacSyntheticKeyup', keysym);
                         };
 
-                    });
+                    }, angular.noop);
 
                 }
 


[03/19] guacamole-client git commit: GUACAMOLE-526: Remove unnecessary use of $q within authenticationService. Rely on requestService.

Posted by vn...@apache.org.
GUACAMOLE-526: Remove unnecessary use of $q within authenticationService. Rely on requestService.


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

Branch: refs/heads/master
Commit: 5be303666a226a53e956f8984054993c9b7a2dd4
Parents: 01e19c1
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Apr 24 15:22:31 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 18:51:45 2018 -0700

----------------------------------------------------------------------
 .../src/main/webapp/app/auth/authModule.js      |  1 +
 .../app/auth/service/authenticationService.js   | 62 +++++---------------
 2 files changed, 16 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5be30366/guacamole/src/main/webapp/app/auth/authModule.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/auth/authModule.js b/guacamole/src/main/webapp/app/auth/authModule.js
index 7faaf87..84c3e33 100644
--- a/guacamole/src/main/webapp/app/auth/authModule.js
+++ b/guacamole/src/main/webapp/app/auth/authModule.js
@@ -21,5 +21,6 @@
  * The module for authentication and management of tokens.
  */
 angular.module('auth', [
+    'rest',
     'storage'
 ]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/5be30366/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 7f74fea..f4a24f9 100644
--- a/guacamole/src/main/webapp/app/auth/service/authenticationService.js
+++ b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
@@ -46,10 +46,9 @@ angular.module('auth').factory('authenticationService', ['$injector',
     var Error                = $injector.get('Error');
 
     // Required services
-    var $http               = $injector.get('$http');
-    var $q                  = $injector.get('$q');
     var $rootScope          = $injector.get('$rootScope');
     var localStorageService = $injector.get('localStorageService');
+    var requestService      = $injector.get('requestService');
 
     var service = {};
 
@@ -155,27 +154,8 @@ angular.module('auth').factory('authenticationService', ['$injector',
      */
     service.authenticate = function authenticate(parameters) {
 
-        var authenticationProcess = $q.defer();
-
-        /**
-         * Stores the given authentication data within the browser and marks
-         * the authentication process as completed.
-         *
-         * @param {Object} data
-         *     The authentication data returned by the token REST endpoint.
-         */
-        var completeAuthentication = function completeAuthentication(data) {
-
-            // Store auth data
-            setAuthenticationResult(new AuthenticationResult(data));
-
-            // Process is complete
-            authenticationProcess.resolve();
-
-        };
-
         // Attempt authentication
-        $http({
+        return requestService({
             method: 'POST',
             url: 'api/tokens',
             headers: {
@@ -185,44 +165,32 @@ angular.module('auth').factory('authenticationService', ['$injector',
         })
 
         // If authentication succeeds, handle received auth data
-        .then(function authenticationSuccessful(response) {
-            var data = response.data;
+        .then(function authenticationSuccessful(data) {
 
             var currentToken = service.getCurrentToken();
+            setAuthenticationResult(new AuthenticationResult(data));
 
             // If a new token was received, ensure the old token is invalidated,
             // if any, and notify listeners of the new token
             if (data.authToken !== currentToken) {
 
-                // If an old token existed, explicitly logout first
+                // If an old token existed, request that the token be revoked
                 if (currentToken) {
-                    service.logout()
-                    ['finally'](function logoutComplete() {
-                        completeAuthentication(data);
-                        $rootScope.$broadcast('guacLogin', data.authToken);
-                    });
+                    service.logout().catch(angular.noop)
                 }
 
-                // Otherwise, simply complete authentication and notify of login
-                else {
-                    completeAuthentication(data);
-                    $rootScope.$broadcast('guacLogin', data.authToken);
-                }
+                // Notify of login and new token
+                $rootScope.$broadcast('guacLogin', data.authToken);
 
             }
 
-            // Otherwise, just finish the auth process
-            else
-                completeAuthentication(data);
+            // Authentication was successful
+            return data;
 
         })
 
         // If authentication fails, propogate failure to returned promise
-        ['catch'](function authenticationFailed(response) {
-
-            // Ensure error object exists, even if the error response is not
-            // coming from the authentication REST endpoint
-            var error = new Error(response.data);
+        ['catch'](function authenticationFailed(error) {
 
             // Request credentials if provided credentials were invalid
             if (error.type === Error.Type.INVALID_CREDENTIALS)
@@ -232,10 +200,10 @@ angular.module('auth').factory('authenticationService', ['$injector',
             else if (error.type === Error.Type.INSUFFICIENT_CREDENTIALS)
                 $rootScope.$broadcast('guacInsufficientCredentials', parameters, error);
 
-            authenticationProcess.reject(error);
-        });
+            // Authentication failed
+            throw error;
 
-        return authenticationProcess.promise;
+        });
 
     };
 
@@ -317,7 +285,7 @@ angular.module('auth').factory('authenticationService', ['$injector',
         $rootScope.$broadcast('guacLogout', token);
 
         // Delete old token
-        return $http({
+        return requestService({
             method: 'DELETE',
             url: 'api/tokens/' + token
         });


[08/19] guacamole-client git commit: GUACAMOLE-526: Add missing semicolon.

Posted by vn...@apache.org.
GUACAMOLE-526: Add missing semicolon.

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

Branch: refs/heads/master
Commit: 2d03387b6bb4a44bbf95a903cf98693f7edcb71c
Parents: f6f66ee
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 19:20:43 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 19:20:43 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/rest/services/requestService.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/2d03387b/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index e06b0d7..be6e1e1 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -41,7 +41,7 @@ angular.module('rest').factory('requestService', ['$q', '$http', 'Error',
             function success(request) { return request.data; },
             function failure(request) { throw new Error(request.data); }
         );
-    }
+    };
 
     return wrappedHttpCall;
 }]);


[16/19] guacamole-client git commit: GUACAMOLE-526: Remove call to old-style $http success().

Posted by vn...@apache.org.
GUACAMOLE-526: Remove call to old-style $http success().

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

Branch: refs/heads/master
Commit: f8bd8d8ec97d2f9d112bafe25b4f5340d5d5cc8c
Parents: ae6b5fc
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 27 00:02:22 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Fri Apr 27 00:02:22 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/rest/services/userService.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f8bd8d8e/guacamole/src/main/webapp/app/rest/services/userService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js
index f05ab31..b044205 100644
--- a/guacamole/src/main/webapp/app/rest/services/userService.js
+++ b/guacamole/src/main/webapp/app/rest/services/userService.js
@@ -264,7 +264,7 @@ angular.module('rest').factory('userService', ['$injector',
         })
 
         // Clear the cache
-        .success(function passwordChanged(){
+        .then(function passwordChanged(){
             cacheService.users.removeAll();
         });
 


[19/19] guacamole-client git commit: GUACAMOLE-526: Merge handle absolutely all promise rejections.

Posted by vn...@apache.org.
GUACAMOLE-526: Merge handle absolutely all promise rejections.


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

Branch: refs/heads/master
Commit: 9d09f0bb0a6bed3b355572644faf374d5ca14f8b
Parents: 9a2e0c6 0d63d6c
Author: Nick Couchman <vn...@apache.org>
Authored: Sun Apr 29 16:57:59 2018 -0400
Committer: Nick Couchman <vn...@apache.org>
Committed: Sun Apr 29 16:57:59 2018 -0400

----------------------------------------------------------------------
 .../src/main/webapp/app/auth/authModule.js      |   1 +
 .../app/auth/service/authenticationService.js   |  62 +++------
 .../app/client/controllers/clientController.js  |  16 ++-
 .../app/client/directives/guacFileBrowser.js    |   2 +-
 .../webapp/app/client/types/ManagedClient.js    |   7 +-
 .../app/client/types/ManagedFileUpload.js       |   7 +-
 .../app/clipboard/services/clipboardService.js  | 125 +++++++++----------
 .../webapp/app/form/directives/formField.js     |   5 +-
 .../app/groupList/directives/guacGroupList.js   |   3 +-
 .../app/home/controllers/homeController.js      |   3 +-
 .../webapp/app/index/config/indexRouteConfig.js |   4 +
 .../app/index/controllers/indexController.js    |   2 +-
 .../webapp/app/index/filters/arrayFilter.js     |   3 -
 .../webapp/app/list/directives/guacUserItem.js  |   2 +-
 .../main/webapp/app/login/directives/login.js   |   5 +-
 .../controllers/manageConnectionController.js   |  57 ++-------
 .../manageConnectionGroupController.js          |  45 ++-----
 .../manageSharingProfileController.js           |  62 +++------
 .../manage/controllers/manageUserController.js  |  56 ++-------
 .../app/navigation/directives/guacUserMenu.js   |   7 +-
 .../app/navigation/services/userPageService.js  |  15 +--
 .../app/notification/notificationModule.js      |   1 +
 .../notification/services/guacNotification.js   |  34 +++++
 .../main/webapp/app/osk/directives/guacOsk.js   |   2 +-
 .../src/main/webapp/app/rest/restModule.js      |   4 +-
 .../rest/services/activeConnectionService.js    |  63 ----------
 .../app/rest/services/connectionGroupService.js |   1 -
 .../app/rest/services/dataSourceService.js      |  13 +-
 .../app/rest/services/permissionService.js      |   1 -
 .../webapp/app/rest/services/requestService.js  |  97 ++++++++++++--
 .../webapp/app/rest/services/userService.js     |   3 +-
 .../directives/guacSettingsConnectionHistory.js |   7 +-
 .../directives/guacSettingsConnections.js       |  17 +--
 .../directives/guacSettingsPreferences.js       |  21 +---
 .../settings/directives/guacSettingsSessions.js |  31 +----
 .../settings/directives/guacSettingsUsers.js    |  20 +--
 36 files changed, 330 insertions(+), 474 deletions(-)
----------------------------------------------------------------------



[13/19] guacamole-client git commit: GUACAMOLE-526: Add convenience callback for displaying modal notifications strictly for REST errors, while logging all other promise rejections.

Posted by vn...@apache.org.
GUACAMOLE-526: Add convenience callback for displaying modal notifications strictly for REST errors, while logging all other promise rejections.

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

Branch: refs/heads/master
Commit: f6d5e5662b643e0521a3069c14639ca03a9a0714
Parents: 1e5e9b6
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 21:20:31 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 21:20:31 2018 -0700

----------------------------------------------------------------------
 guacamole/src/main/webapp/app/rest/restModule.js  |  5 ++++-
 .../webapp/app/rest/services/requestService.js    | 18 ++++++++++++++++--
 2 files changed, 20 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f6d5e566/guacamole/src/main/webapp/app/rest/restModule.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/restModule.js b/guacamole/src/main/webapp/app/rest/restModule.js
index 81b64b5..6672507 100644
--- a/guacamole/src/main/webapp/app/rest/restModule.js
+++ b/guacamole/src/main/webapp/app/rest/restModule.js
@@ -21,4 +21,7 @@
  * The module for code relating to communication with the REST API of the
  * Guacamole web application.
  */
-angular.module('rest', ['auth']);
+angular.module('rest', [
+    'auth',
+    'notification'
+]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f6d5e566/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index 9aef124..a27ccc3 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -25,8 +25,9 @@ angular.module('rest').factory('requestService', ['$injector',
         function requestService($injector) {
 
     // Required services
-    var $http = $injector.get('$http');
-    var $log  = $injector.get('$log');
+    var $http            = $injector.get('$http');
+    var $log             = $injector.get('$log');
+    var guacNotification = $injector.get('guacNotification');
 
     // Required types
     var Error = $injector.get('Error');
@@ -115,6 +116,19 @@ angular.module('rest').factory('requestService', ['$injector',
         $log.warn(error.type, error.message || error.translatableMessage);
     });
 
+    /**
+     * Promise error callback which displays a modal notification for all
+     * rejections due to REST errors. The message displayed to the user within
+     * the notification is provided by the contents of the @link{Error} object
+     * within the REST response. All other rejections, such as those due to
+     * JavaScript errors, are logged to the browser console without displaying
+     * any notification.
+     *
+     * @constant
+     * @type Function
+     */
+    service.SHOW_NOTIFICATION = service.createErrorCallback(guacNotification.showRequestError);
+
     return service;
 
 }]);


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

Posted by vn...@apache.org.
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);
             
         }]
     };


[15/19] guacamole-client git commit: GUACAMOLE-526: Move handling of request error notification to guacNotification, resolving circular dependency.

Posted by vn...@apache.org.
GUACAMOLE-526: Move handling of request error notification to guacNotification, resolving circular dependency.

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

Branch: refs/heads/master
Commit: ae6b5fc8bbc67822308c5aaf038bb2456c6d21f4
Parents: 266b445
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 22:28:18 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 22:28:18 2018 -0700

----------------------------------------------------------------------
 .../controllers/manageConnectionController.js   |  4 ++--
 .../manageConnectionGroupController.js          |  4 ++--
 .../manageSharingProfileController.js           |  4 ++--
 .../manage/controllers/manageUserController.js  |  6 ++---
 .../app/notification/notificationModule.js      |  1 +
 .../notification/services/guacNotification.js   | 23 ++++++++++----------
 .../src/main/webapp/app/rest/restModule.js      |  3 +--
 .../webapp/app/rest/services/requestService.js  | 18 ++-------------
 .../directives/guacSettingsPreferences.js       |  2 +-
 .../settings/directives/guacSettingsSessions.js |  2 +-
 10 files changed, 26 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 66e2aeb..2bbd999 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -379,7 +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');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
     
@@ -419,7 +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');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 cab4b18..de29aff 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -221,7 +221,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
         connectionGroupService.saveConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
         .then(function savedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
     
@@ -261,7 +261,7 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
         connectionGroupService.deleteConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
         .then(function deletedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 886f54c..5f2d6bd 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -342,7 +342,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
         .then(function savedSharingProfile() {
             $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
 
@@ -370,7 +370,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
         .then(function deletedSharingProfile() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 d0b6be4..eae141b 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -1141,9 +1141,9 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
             permissionService.patchPermissions(selectedDataSource, $scope.user.username, permissionsAdded, permissionsRemoved)
             .then(function patchedUserPermissions() {
                 $location.url('/settings/users');
-            }, requestService.SHOW_NOTIFICATION);
+            }, guacNotification.SHOW_REQUEST_ERROR);
 
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
     
@@ -1183,7 +1183,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         userService.deleteUser(selectedDataSource, $scope.user)
         .then(function deletedUser() {
             $location.path('/settings/users');
-        }, requestService.SHOW_NOTIFICATION);
+        }, guacNotification.SHOW_REQUEST_ERROR);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/guacamole/src/main/webapp/app/notification/notificationModule.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/notification/notificationModule.js b/guacamole/src/main/webapp/app/notification/notificationModule.js
index 9a4eb0c..15a2a46 100644
--- a/guacamole/src/main/webapp/app/notification/notificationModule.js
+++ b/guacamole/src/main/webapp/app/notification/notificationModule.js
@@ -21,5 +21,6 @@
  * The module for code used to display arbitrary notifications.
  */
 angular.module('notification', [
+    'rest',
     'storage'
 ]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/guacamole/src/main/webapp/app/notification/services/guacNotification.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/notification/services/guacNotification.js b/guacamole/src/main/webapp/app/notification/services/guacNotification.js
index a1b8d10..b52f421 100644
--- a/guacamole/src/main/webapp/app/notification/services/guacNotification.js
+++ b/guacamole/src/main/webapp/app/notification/services/guacNotification.js
@@ -25,6 +25,7 @@ angular.module('notification').factory('guacNotification', ['$injector',
 
     // Required services
     var $rootScope            = $injector.get('$rootScope');
+    var requestService        = $injector.get('requestService');
     var sessionStorageFactory = $injector.get('sessionStorageFactory');
 
     var service = {};
@@ -93,26 +94,24 @@ angular.module('notification').factory('guacNotification', ['$injector',
     };
 
     /**
-     * Shows the given REST error response as a modal status. If a status
-     * notification is already currently shown, this function will have no
-     * effect.
+     * Promise error callback which displays a modal notification for all
+     * rejections due to REST errors. The message displayed to the user within
+     * the notification is provided by the contents of the @link{Error} object
+     * within the REST response. All other rejections, such as those due to
+     * JavaScript errors, are logged to the browser console without displaying
+     * any notification.
      *
-     * @param {Error} error
-     *     The error object returned from the failed REST request.
-     *
-     * @example
-     *
-     * someService.updateObject(object)
-     * ['catch'](guacNotification.showRequestError);
+     * @constant
+     * @type Function
      */
-    service.showRequestError = function showRequestError(error) {
+    service.SHOW_REQUEST_ERROR = requestService.createErrorCallback(function showRequestError(error) {
         service.showStatus({
             className  : 'error',
             title      : 'APP.DIALOG_HEADER_ERROR',
             text       : error.translatableMessage,
             actions    : [ service.ACKNOWLEDGE_ACTION ]
         });
-    };
+    });
 
     // Hide status upon navigation
     $rootScope.$on('$routeChangeSuccess', function() {

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/guacamole/src/main/webapp/app/rest/restModule.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/restModule.js b/guacamole/src/main/webapp/app/rest/restModule.js
index 6672507..f409e95 100644
--- a/guacamole/src/main/webapp/app/rest/restModule.js
+++ b/guacamole/src/main/webapp/app/rest/restModule.js
@@ -22,6 +22,5 @@
  * Guacamole web application.
  */
 angular.module('rest', [
-    'auth',
-    'notification'
+    'auth'
 ]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index a27ccc3..9aef124 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -25,9 +25,8 @@ angular.module('rest').factory('requestService', ['$injector',
         function requestService($injector) {
 
     // Required services
-    var $http            = $injector.get('$http');
-    var $log             = $injector.get('$log');
-    var guacNotification = $injector.get('guacNotification');
+    var $http = $injector.get('$http');
+    var $log  = $injector.get('$log');
 
     // Required types
     var Error = $injector.get('Error');
@@ -116,19 +115,6 @@ angular.module('rest').factory('requestService', ['$injector',
         $log.warn(error.type, error.message || error.translatableMessage);
     });
 
-    /**
-     * Promise error callback which displays a modal notification for all
-     * rejections due to REST errors. The message displayed to the user within
-     * the notification is provided by the contents of the @link{Error} object
-     * within the REST response. All other rejections, such as those due to
-     * JavaScript errors, are logged to the browser console without displaying
-     * any notification.
-     *
-     * @constant
-     * @type Function
-     */
-    service.SHOW_NOTIFICATION = service.createErrorCallback(guacNotification.showRequestError);
-
     return service;
 
 }]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 6cfd440..dfad564 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
@@ -165,7 +165,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                         },
                         actions : [ ACKNOWLEDGE_ACTION ]
                     });
-                }, requestService.SHOW_NOTIFICATION);
+                }, guacNotification.SHOW_REQUEST_ERROR);
                 
             };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/ae6b5fc8/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 8563d52..67776f0 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsSessions.js
@@ -316,7 +316,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti
                     // Clear selection
                     allSelectedWrappers = {};
 
-                }, requestService.SHOW_NOTIFICATION);
+                }, guacNotification.SHOW_REQUEST_ERROR);
 
             }; 
             


[18/19] guacamole-client git commit: GUACAMOLE-526: Only pull primary connection for sharing profile once identifier is known.

Posted by vn...@apache.org.
GUACAMOLE-526: Only pull primary connection for sharing profile once identifier is known.

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

Branch: refs/heads/master
Commit: 0d63d6cef442b35e3892305500bffb88b81c16da
Parents: 2ff980d
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Apr 27 00:12:36 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Fri Apr 27 00:12:36 2018 -0700

----------------------------------------------------------------------
 .../manage/controllers/manageSharingProfileController.js | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/0d63d6ce/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 5f2d6bd..7414e65 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -261,11 +261,12 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     $scope.$watch('sharingProfile.primaryConnectionIdentifier',
         function retrievePrimaryConnection(identifier) {
 
-        // Pull data from existing sharing profile
-        connectionService.getConnection($scope.selectedDataSource, identifier)
-        .then(function connectionRetrieved(connection) {
-            $scope.primaryConnection = connection;
-        }, requestService.WARN);
+        if (identifier) {
+            connectionService.getConnection($scope.selectedDataSource, identifier)
+            .then(function connectionRetrieved(connection) {
+                $scope.primaryConnection = connection;
+            }, requestService.WARN);
+        }
 
     });
 


[11/19] guacamole-client git commit: GUACAMOLE-526: Add convenience callbacks for ignoring or (quietly) warning of REST errors.

Posted by vn...@apache.org.
GUACAMOLE-526: Add convenience callbacks for ignoring or (quietly) warning of REST errors.

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

Branch: refs/heads/master
Commit: cc6ade49171627cd89075ab91cde9317196989c2
Parents: c30b7b0
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 21:19:22 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 21:19:22 2018 -0700

----------------------------------------------------------------------
 .../webapp/app/rest/services/requestService.js  | 26 +++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/cc6ade49/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index b2f709b..9aef124 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -91,6 +91,30 @@ angular.module('rest').factory('requestService', ['$injector',
         });
     };
 
-   return service;
+    /**
+     * Promise error callback which ignores all rejections due to REST errors,
+     * but logs all other rejections, such as those due to JavaScript errors.
+     * This callback should be used in favor of angular.noop in cases where
+     * a REST response is being handled but REST errors should be ignored.
+     *
+     * @constant
+     * @type Function
+     */
+    service.IGNORE = service.createErrorCallback(angular.noop);
+
+    /**
+     * Promise error callback which logs all rejections due to REST errors as
+     * warnings to the browser console, and logs all other rejections as
+     * errors. This callback should be used in favor of angular.noop or
+     * @link{IGNORE} if REST errors are simply not expected.
+     *
+     * @constant
+     * @type Function
+     */
+    service.WARN = service.createErrorCallback(function warnRequestFailed(error) {
+        $log.warn(error.type, error.message || error.translatableMessage);
+    });
+
+    return service;
 
 }]);


[09/19] guacamole-client git commit: GUACAMOLE-526: Wrap HTTP response in Error object only if it's an actual HTTP response object.

Posted by vn...@apache.org.
GUACAMOLE-526: Wrap HTTP response in Error object only if it's an actual HTTP response object.

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

Branch: refs/heads/master
Commit: 8c9735d1e7da1a33928b70b4be6659dbf4bc711a
Parents: 2d03387
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 20:57:18 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 20:57:18 2018 -0700

----------------------------------------------------------------------
 .../webapp/app/rest/services/requestService.js  | 42 +++++++++++++++-----
 1 file changed, 31 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/8c9735d1/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
index be6e1e1..f17ce25 100644
--- a/guacamole/src/main/webapp/app/rest/services/requestService.js
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -21,27 +21,47 @@
  * Service for converting $http promises that pass the entire response into
  * promises that pass only the data from that response.
  */
-angular.module('rest').factory('requestService', ['$q', '$http', 'Error',
-        function requestService($q, $http, Error) {
+angular.module('rest').factory('requestService', ['$injector',
+        function requestService($injector) {
+
+    // Required services
+    var $http = $injector.get('$http');
+
+    // Required types
+    var Error = $injector.get('Error');
 
     /**
      * Given a configuration object formatted for the $http service, returns
-     * a promise that will resolve or reject with only the data from the $http
-     * response.
+     * a promise that will resolve or reject with the data from the HTTP
+     * response. If the promise is rejected due to the HTTP response indicating
+     * failure, the promise will be rejected strictly with an instance of an
+     * @link{Error} object.
      *
      * @param {Object} object
      *   Configuration object for $http service call.
      *
-     * @returns {Promise}
-     *   A promise that will resolve or reject with the data from the response
-     *   to the $http call.
+     * @returns {Promise.<Object>}
+     *   A promise that will resolve with the data from the HTTP response for
+     *   the underlying $http call if successful, or reject with an @link{Error}
+     *   describing the failure.
      */
-    var wrappedHttpCall = function wrappedHttpCall(object) {
+    var service = function wrapHttpServiceCall(object) {
         return $http(object).then(
-            function success(request) { return request.data; },
-            function failure(request) { throw new Error(request.data); }
+            function success(response) { return response.data; },
+            function failure(response) {
+
+                // Wrap true error responses from $http within REST Error objects
+                if (response.data)
+                    throw new Error(response.data);
+
+                // The value provided is not actually a response object from
+                // the $http service
+                throw response;
+
+            }
         );
     };
 
-    return wrappedHttpCall;
+    return service;
+
 }]);