![]()
When using AngularJS routing with $routeProvider, route changes may sometimes fail due to missing templates, failed module loads, or authentication issues. Properly handling these errors ensures a smooth user experience by showing meaningful messages instead of a blank screen or console errors.
1. Why Handle Route Change Errors?
- Prevent application crashes due to missing resources.
- Provide user-friendly error messages instead of raw errors.
- Improve debugging and monitoring by logging issues.
- Enhance user experience by redirecting to fallback pages.
2. Key AngularJS Events for Handling Route Errors
AngularJS provides two key events that help detect route change issues:
$routeChangeError– Fires when an error occurs while resolving a route.$routeChangeStart– Fires before a route change begins, useful for authentication checks.
3. Implementing Global Route Error Handling
Step 1: Listen for $routeChangeError in app.run()
var app = angular.module("myApp", ["ngRoute"]);
app.run(["$rootScope", "$location", function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
console.error("Route Change Error:", rejection);
// Redirect user to a custom error page
$location.path("/error");
});
}]);
How This Works:
- Whenever an error occurs during route changes, it logs the error and redirects the user to
/error.
Step 2: Create an Error Route in $routeProvider
Modify the routing configuration to include an error page:
app.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "home.html",
controller: "HomeController"
})
.when("/dashboard", {
templateUrl: "dashboard.html",
controller: "DashboardController",
resolve: {
load: function($q, $timeout) {
var deferred = $q.defer();
// Simulate an error (e.g., module load failure)
$timeout(function() {
deferred.reject("Failed to load dashboard data");
}, 1000);
return deferred.promise;
}
}
})
.when("/error", {
template: "<h2>Error</h2><p>Something went wrong! Please try again later.</p>"
})
.otherwise({
redirectTo: "/"
});
}]);
How This Works:
- If the
/dashboardroute fails to load, the error is caught by$routeChangeError, and the user is redirected to/error.
4. Handling Authentication Errors in Route Resolves
Sometimes, users may try to access restricted pages. Handle authentication errors like this:
app.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/dashboard", {
templateUrl: "dashboard.html",
controller: "DashboardController",
resolve: {
auth: function($q, AuthService) {
var deferred = $q.defer();
if (AuthService.isAuthenticated()) {
deferred.resolve();
} else {
deferred.reject("Unauthorized access");
}
return deferred.promise;
}
}
});
}]);
app.run(["$rootScope", "$location", function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
if (rejection === "Unauthorized access") {
alert("You must log in to access this page.");
$location.path("/");
}
});
}]);
app.service("AuthService", function() {
this.isAuthenticated = function() {
return false; // Change this logic based on real authentication
};
});
How This Works:
- Before loading
/dashboard,AuthService.isAuthenticated()checks user authentication. - If unauthorized,
$routeChangeErrortriggers and redirects the user.
5. Displaying a Custom Error Message on the UI
Modify the $rootScope listener to store the error message:
app.run(["$rootScope", "$location", function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
console.error("Route Change Error:", rejection);
// Store the error message in rootScope
$rootScope.errorMessage = rejection;
$location.path("/error");
});
}]);
Modify error.html to Show the Error Message
<h2>Error</h2>
<p>{{ errorMessage || "An unexpected error occurred. Please try again." }}</p>
Now the error message is displayed dynamically instead of a generic message.
6. Advanced Error Handling: Logging Errors to a Server
To log errors remotely, modify $routeChangeError to send logs to a backend service:
app.run(["$rootScope", "$location", "$http", function($rootScope, $location, $http) {
$rootScope.$on("$routeChangeError", function(event, current, previous, rejection) {
console.error("Route Change Error:", rejection);
// Send error details to the server
$http.post("/logError", {
url: current.loadedTemplateUrl,
error: rejection
});
$location.path("/error");
});
}]);
This helps monitor and debug errors in production.
