(function(angular) { 'use strict'; var app = angular.module("app", []); app.factory('$exceptionHandler', ['$log', '$injector', '$svcLog', svcExceptionHandler]); app.factory('$svcLogHttp', ['$http', svcLogHttp]); app.factory('$svcLog', [svcLog]); app.controller("ctrlHome", ["$scope", function($scope) { console.log('controller init'); $scope.createError = function() { invalid.data = 'this is an error on the controller'; } $scope.$on('app-error', function(event, args) { $scope.error = args.message; $scope.stack = args.stack; }); } ]); //using $http service. this creates a circular reference function svcLogHttp($http) { var svc = { add: add } function add(exception) { //simulate sending the error here $http.post('/api/log', exception).then(function(resp) { console.log(); }, function(err) { console.log(err); }); } return svc; } //just using jquery no circular reference function svcLog() { var svc = { add: add } function add(exception) { //simulate sending the error here var data = angular.toJson(exception); console.log('Sending to the server - ' + data); $.ajax({ type: "POST", url: "/api/log", contentType: "application/json", data: data }); } return svc; } //this service uses either the injected $svcLog or inject $svcLogHttp to avoid circular reference function svcExceptionHandler($log, $injector, $svcLog, $rootScope) { var $svc = $svcLog; var $rootScope = null; var handler = function(exception, cause) { var ex = { message: exception.message, stack: exception.stack }; //log to console and allow the app to continue $log.error.apply($log, arguments); try { if (!$svc) { $svc = $injector.get('$svcLogHttp'); } if (!$rootScope) { $rootScope = $injector.get('$rootScope'); } //send the error $rootScope.$broadcast('app-error', ex); $svc.add(ex); } catch (err) { $log.log(err); } }; return handler; } }(angular));
<div ng-app="app"> <div ng-controller="ctrlHome as ctrl"> <div class="body-content panel-body text-center"> <h2 class="text-info">AngularJS Server Side Exception Logging by ozkary.com</h2> <div class="row"> <div class="col-sm-12"> <div class=""> <input class="btn btn-primary btn-large" type="button" ng-click="createError()" value="Click to raise error" /> </div> </div> </div> <div class="row"> <div class="col-sm-12"> <h3>Message</h3> <div ng-bind="error" class="bg-warning container" style="padding:15px;"> </div> <h2>Stack</h2> <div ng-bind="stack" class="bg-warning container" style="padding:15px;"> </div> </div> </div> </div> </div> </div>