Using $httpInterceptor for API error handling

Loading

Handling API errors efficiently is crucial for maintaining a smooth user experience in an AngularJS application. The $httpInterceptor service allows you to globally intercept and modify HTTP requests and responses, making it an excellent choice for handling API errors centrally.


1. What is $httpInterceptor?

An $httpInterceptor is a factory function that allows you to modify HTTP requests and responses globally before they reach the server or the client. It helps in:

Logging API errors centrally
Showing user-friendly messages for failed requests
Retrying failed requests if needed
Redirecting users to the login page if authentication fails


2. Creating an $httpInterceptor for API Error Handling

Step 1: Define the Interceptor

Create a new factory for $httpInterceptor and inject it into your module.

angular.module('myApp')
.factory('httpErrorInterceptor', function($q, $injector) {
return {
// Intercept response errors
responseError: function(rejection) {
let $rootScope = $injector.get('$rootScope'); // Inject dynamically
let $state = $injector.get('$state'); // Get current state (for redirection)

console.error("HTTP Error:", rejection); // Log the error

// Handle different types of errors
if (rejection.status === 401) { // Unauthorized
$rootScope.$broadcast('unauthorized'); // Notify listeners
$state.go('login'); // Redirect to login page
}
else if (rejection.status === 403) { // Forbidden
alert("You don't have permission to access this resource.");
}
else if (rejection.status === 404) { // Not Found
alert("Requested resource not found.");
}
else if (rejection.status === 500) { // Internal Server Error
alert("Server error! Please try again later.");
}

return $q.reject(rejection); // Reject the promise with the error
}
};
});

Step 2: Register the Interceptor in the $httpProvider

After defining the interceptor, register it inside the .config() block.

angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.interceptors.push('httpErrorInterceptor');
});

Automatically intercepts all HTTP requests and responses
Handles API errors centrally


3. Displaying Global Error Messages Using $rootScope

If you want to show an error message whenever an API request fails, use $rootScope.$broadcast().

Step 1: Broadcast Errors from the Interceptor

Modify the interceptor to notify the entire app about errors.

.factory('httpErrorInterceptor', function($q, $rootScope) {
return {
responseError: function(rejection) {
$rootScope.$broadcast('httpError', rejection);
return $q.reject(rejection);
}
};
});

Step 2: Listen for API Errors in a Controller

Now, listen for API errors globally in the main controller.

angular.module('myApp')
.controller('MainController', function($scope) {
$scope.errorMessage = '';

$scope.$on('httpError', function(event, rejection) {
$scope.errorMessage = "API Error: " + rejection.statusText;
});
});

Shows error messages in the UI dynamically


4. Retrying Failed Requests Automatically

Sometimes, API calls fail due to temporary issues (e.g., network problems). You can retry failed requests automatically inside the interceptor.

Step 1: Modify the Interceptor to Retry Requests

.factory('httpRetryInterceptor', function($q, $injector, $timeout) {
return {
responseError: function(rejection) {
if (rejection.status === 500) { // Retry only on server errors
let $http = $injector.get('$http');
return $timeout(() => $http(rejection.config), 2000); // Retry after 2 seconds
}
return $q.reject(rejection);
}
};
});

Retries requests automatically if the server returns a 500 error
Uses $timeout() to delay retry attempts


5. Redirecting to Login Page on Unauthorized (401) Responses

When a user’s session expires, APIs may return a 401 Unauthorized error. You can redirect users to the login page automatically when this happens.

Modify the Interceptor to Handle 401 Errors

.factory('authInterceptor', function($q, $injector) {
return {
responseError: function(rejection) {
if (rejection.status === 401) { // Unauthorized
let $state = $injector.get('$state');
$state.go('login'); // Redirect to login
}
return $q.reject(rejection);
}
};
});

Automatically redirects to login when authentication fails


6. Adding Authentication Tokens to Requests

For authenticated API requests, you need to attach an auth token (e.g., JWT) to the request headers.

Modify Requests to Include an Auth Token

.factory('authTokenInterceptor', function($q, AuthService) {
return {
request: function(config) {
let token = AuthService.getToken();
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
return config;
}
};
});

Ensures all API requests include an authentication token

Leave a Reply

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