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");
}
};