Understanding $exceptionHandler and Custom Error Handling in AngularJS

Loading

AngularJS provides a built-in $exceptionHandler service to handle uncaught exceptions in an application. By default, it logs errors to the browser console. However, we can override it to implement custom error handling, such as logging errors to a server or displaying user-friendly messages.


1. Default Behavior of $exceptionHandler

By default, AngularJS logs unhandled errors using $exceptionHandler.

Example of Unhandled Exception

app.controller('TestController', function($scope) {
throw new Error("This is an unhandled error!");
});

This error is logged to the console but does not show any user-friendly message.


2. Creating a Custom $exceptionHandler Service

We can override $exceptionHandler to log errors to a remote server or show alerts.

Custom $exceptionHandler Service

app.factory('$exceptionHandler', function($log, $window) {
return function(exception, cause) {
// Log error to console
$log.error("Exception: ", exception);
$log.error("Cause: ", cause);

// Show an alert to the user
alert("An unexpected error occurred: " + exception.message);

// Send error details to a server (optional)
$window.fetch('/logError', {
method: 'POST',
body: JSON.stringify({
message: exception.message,
stack: exception.stack,
cause: cause
}),
headers: { 'Content-Type': 'application/json' }
});
};
});

Breakdown:
✔ Logs error messages using $log.error().
✔ Displays an alert for user-friendly feedback.
✔ Sends the error to a remote server using $window.fetch().


3. Using $exceptionHandler Inside a Controller

We can manually invoke $exceptionHandler in controllers or services.

Example: Manually Triggering an Exception

app.controller('MainController', function($scope, $exceptionHandler) {
$scope.triggerError = function() {
try {
throw new Error("Something went wrong!");
} catch (error) {
$exceptionHandler(error, "Triggered manually");
}
};
});

4. Handling Errors in Promises ($q)

When working with promises, errors can be caught using .catch().

Example: Handling Promise Errors

app.service('DataService', function($http, $q) {
this.getData = function() {
return $http.get('/invalid-url').catch(function(error) {
throw new Error("Failed to fetch data: " + error.statusText);
});
};
});

5. Global Error Handling Using $rootScope

We can handle all errors globally using $rootScope.$on("$routeChangeError").

Example: Catching Routing Errors

app.run(function($rootScope, $exceptionHandler) {
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
$exceptionHandler(rejection, "Routing Error");
});
});

6. Preventing Errors from Breaking the Application

To gracefully handle errors, wrap risky code inside try-catch blocks.

Safe Function Execution

$scope.safeFunction = function() {
try {
riskyOperation();
} catch (error) {
$exceptionHandler(error, "Safe Execution");
}
};

Leave a Reply

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