pinalbhatt
3/25/2015 - 2:41 PM

AngularJS Exception Module

AngularJS Exception Module

(function() {
    'use strict';

    angular.module('PBDesk.Exception', ['PBDesk.Logger'])
        .factory('exception', exception)
        .provider('ExceptionHandler', ExceptionHandlerProvider)
        .config(config);

    exception.$inject = ['Logger'];

    function exception(logger) {
        var service = {
            catcher: catcher
        };
        return service;

        function catcher(message) {
            return function(reason) {
                logger.error(message, reason);
            };
        }
    }
    
    /**
     * Must configure the exception handling
     * @return {[type]}
     */
    function ExceptionHandlerProvider() {
      
        this.config = {
            appErrorPrefix: undefined
        };

        this.configure = function (appErrorPrefix) {
            this.config.appErrorPrefix = appErrorPrefix;
        };

        this.$get = function() {
            return {config: this.config};
        };
    }

    /**
     * Configure by setting an optional string value for appErrorPrefix.
     * Accessible via config.appErrorPrefix (via config value).
     * @param  {[type]} $provide
     * @return {[type]}
     * @ngInject
     */
    function config($provide) {
        $provide.decorator('$exceptionHandler', extendExceptionHandler);
    }

    /**
     * Extend the $exceptionHandler service to also display a toast.
     * @param  {Object} $delegate
     * @param  {Object} ExceptionHandler
     * @param  {Object} logger
     * @return {Function} the decorated $exceptionHandler service
     */
    function extendExceptionHandler($delegate, ExceptionHandler, Logger) {
        return function(exception, cause) {
            var appErrorPrefix = ExceptionHandler.config.appErrorPrefix || '';
            var errorData = {exception: exception, cause: cause};
            exception.message = appErrorPrefix + exception.message;
            $delegate(exception, cause);
            /**
             * Could add the error to a service's collection,
             * add errors to $rootScope, log errors to remote web server,
             * or log locally. Or throw hard. It is entirely up to you.
             * throw exception;
             *
             * @example
             *     throw { message: 'error message we added' };
             */
            Logger.error(exception.message, errorData);
        };
    }
})();