Using $exceptionHandler to catch global errors

Loading

In AngularJS, $exceptionHandler is a built-in service used to catch and handle unhandled exceptions globally. By default, it logs errors to the browser console, but you can customize it to log errors to a remote server, display user-friendly messages, or perform additional debugging actions.


1. Default Behavior of $exceptionHandler

By default, AngularJS logs unhandled exceptions using console.error().
For example:

angular.module('myApp', [])
.controller('myController', function($scope) {
$scope.throwError = function() {
throw new Error("Something went wrong!");
};
});
  • If you call $scope.throwError(), the browser console will show: javascriptCopyEditError: Something went wrong!
  • This default behavior does not provide centralized error tracking.

2. Customizing $exceptionHandler

To override $exceptionHandler, define a custom exception handler inside an AngularJS config block.

Example: Logging Errors to Console and Server

angular.module('myApp', [])
.config(function($provide) {
$provide.decorator('$exceptionHandler', function($delegate, $log) {
return function(exception, cause) {
// Log the error to the console
$log.error("Error:", exception);

// Send error details to a remote server
sendErrorToServer(exception, cause);

// Call the original AngularJS exception handler
$delegate(exception, cause);
};
});
});

// Simulating an API call to send error logs
function sendErrorToServer(exception, cause) {
console.log("Sending error details to server:", exception.message, "Cause:", cause);
}

How This Works

  1. $provide.decorator is used to override the default $exceptionHandler.
  2. $delegate preserves the original error-handling behavior.
  3. Logs the error using $log.error() for debugging.
  4. Sends error details to a remote server (e.g., for monitoring or analytics).
  5. Calls the original exception handler to ensure AngularJS’s internal handling remains intact.

3. Handling Errors in Controllers

Even with a global exception handler, it’s good practice to handle errors locally in controllers.

Example: Using try-catch to Catch Errors in a Controller

angular.module('myApp', [])
.controller('myController', function($scope, $exceptionHandler) {
$scope.safeAction = function() {
try {
throw new Error("Controller error!");
} catch (error) {
$exceptionHandler(error, "safeAction function");
}
};
});
  • This prevents the app from breaking due to uncaught exceptions.
  • $exceptionHandler(error, "Function name") logs errors globally while keeping the app functional.

4. Catching Asynchronous Errors

AngularJS does not automatically catch async errors (e.g., in $http or $timeout). Use .catch() to handle these errors.

Example: Handling $http Errors

angular.module('myApp', [])
.controller('myController', function($scope, $http, $exceptionHandler) {
$scope.getData = function() {
$http.get('invalid_url')
.then(function(response) {
$scope.data = response.data;
})
.catch(function(error) {
$exceptionHandler(error, "HTTP Request Error");
});
};
});
  • Without .catch(), HTTP errors won’t trigger $exceptionHandler.
  • Use .catch(error => $exceptionHandler(error, "Message")) to track API failures.

5. Tracking User-Specific Errors

If you need to log errors along with user details, modify $exceptionHandler to include user session data.

Example: Logging Errors with User Info

angular.module('myApp', [])
.config(function($provide) {
$provide.decorator('$exceptionHandler', function($delegate, $log, UserService) {
return function(exception, cause) {
let user = UserService.getCurrentUser();
let errorDetails = {
message: exception.message,
stack: exception.stack,
cause: cause,
user: user
};
$log.error("User Error:", errorDetails);
sendErrorToServer(errorDetails);
$delegate(exception, cause);
};
});
});

// Simulated UserService
angular.module('myApp').service('UserService', function() {
this.getCurrentUser = function() {
return { id: 101, name: "John Doe" };
};
});
  • Captures user details with every error.
  • Helps in debugging user-specific issues.

6. Preventing Errors in Production

To disable detailed error logs in production, use $logProvider.debugEnabled(false).

Example: Disable Debugging Logs in Production

angular.module('myApp', [])
.config(function($logProvider) {
$logProvider.debugEnabled(false);
});
  • This prevents sensitive error details from being logged.
  • Instead, errors can be sent to a monitoring service.

Leave a Reply

Your email address will not be published. Required fields are marked *