I am building an App with ionic and I want to handle the 500 internal server error which occurs in $http() AJAX call. Is it possible to create any interceptors to handle that?
here is my controller code:
.controller('RegistrationController',function($scope,$http){
$scope.doRegistration = function(){
$http({
method : "POST",
url : BASE_URL,
params : {
//sending the parameters as JSON
}
}).then(function successCallback(response){
if(response.status == 200)
//handling the response sent by server
},function errorCallback()});
};
});
if the user enters some invalid inputs and the server is unable to handle that it throws 500 Internal Server Error. When the AJAX call is made I am showing a spinner and when some server error occurs I should stop the AJAX call and stop the spinner and show some popup to user saying "Encountered server error".
'use strict';
angular.module('myApp').factory('MyService', function ($http, $q) {
var BASE_URL = 'some.url.com';
function register() {
var defer = $q.defer();
$http({method: "POST", url: BASE_URL, params: {}})
.then(function (response) {
defer.resolve(response.data);
})
.catch(function (reason) {
defer.resolve(reason);
});
return defer.promise;
}
return {
register: register
}
}).controller('MyController', function ($scope, MyService) {
MyService.register().then(function (response) {
// success
}).catch(function (reason) {
// err
if (reason.status === 500) {
// do something
$scope.spinner = false;
console.log('Encountered server error');
}
});
});
you can create interceptor as below -
app.factory('testResponseInterceptor', function ($q ,$rootScope,$location) {
return {
response: function (response) {
//correct response
return response;
},
responseError: function (response) {
//error in response
}
};
});
and configure it in your module -
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('testResponseInterceptor');
});
Related
Hi this below is my code from angularjs
The first part of the code shows exactly how I make the request to php which returns me data when there is code with an error when there is a problem.
When it returns me an error code, for example 401, the frontend explodes with an error and everything breaks.
As far as I understand, I have to use an interceptor so that I can catch the error number and not make an error.
I can't do this interception.
app.js
app.factory('httpRequester', function ($http, $route) {
var promise;
var myService = {
async: function (myData) {
//Create my obj for request
var req = {
method: myData.Method,
url: 'https://**********/' + url,
headers: {
'X-API-KEY': '**************',
'KEY': myData.Authentication.AccessToken
},
data: myData
};
promise = $http(req).then(function (response) {
if (response.data === 'permission denied') {
window.location.href = '#/';
} else {
return response;
}
});
return promise;
}
};
return myService;
});
//set interceptor in app.js
var interceptorApp = angular.module('interceptorApp', []);
interceptorApp.config(function($httpProvider) {
$httpProvider.interceptors.push('genericInterceptor');
});
Please help me with my problem, how to set interceptor work.
//Function for set error and success after request
var testInterceptor = function ($q)
{
return {
request: function (config)
{
//console.log('request started...');
},
requestError: function (rejection)
{
console.log(rejection);
// Contains the data about the error on the request and return the promise rejection.
return $q.reject(rejection);
},
response: function (result)
{
// console.log('data for ' + result.data.name + ' received');
//If some manipulation of result is required before assigning to scope.
result["testKey"] = 'testValue';
console.log('request completed');
return result;
},
responseError: function (response)
{
// console.log('response error started...');
//Check different response status and do the necessary actions 400, 401, 403,401, or 500 eror
return $q.reject(response);
}
}
}
I get a value of "True" in my response. How come my debugger and alert and AccessGranted() in the .then of my $http is not being invoked. Below is my Script:
app.controller("LoginController", function($scope, $http) {
$scope.btnText = "Enter";
$scope.message = "";
$scope.login = function() {
$scope.btnText = "Please wait...";
$scope.message = "We're logging you in.";
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
}).then(function (response) {
debugger;
alert(response.data);
if (response.data == "True") {
AccessGranted();
} else {
$scope.message = response.data;
$scope.btnText = "Enter";
}
},
function (error) {
$scope.message = 'Sending error: ' + error;
});
}
$scope.AccessGranted = function() {
window.location.pathname("/Home/HomeIndex");
}
});
This is in my HomeController
public ActionResult HomeIndex()
{
var am = new AuditManager();
var auditModel = new AuditModel()
{
AccountId = 0,
ActionDateTime = DateTime.Now,
ActionName = "Home",
ActionResult = "Redirected to Home"
};
am.InsertAudit(auditModel);
return View("Index");
}
Please see image for the response I get.
seems like your approach is wrong
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Try this,
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
})
.then(function (response) {
console.log(response);
},
function (error) {
console.log(error);
});
And check your browser console for logs or any errors
Make sure the response is application/json content type, and content is json.
You can also write own httpProvider for check result from server
module.config(['$httpProvider', function ($httpProvider) {
...
I would suggest you to code like this instead of then so whenever there is success, The success part will be invoked.
$http.get('/path/').success(function (data) {
$scope.yourdata = data.data;
//console.log($scope.yourdata);
}).error(function (error){
//error part
});
This is http interceptor service that should handle cancellation of previous requests with the same url. I have a problem with handling rejection after calling 'resolve' method which falls into a 'catch' handler of my angular data service.
How to flag this cancellation as intentional, so my data service does not indicate that an error occurred on server side? I don't want to display error message in this case.
(function () {
'use strict';
angular
.module('common')
.factory('abortService', abortService);
abortService.$inject = ['$q', '$filter'];
function abortService($q, $filter) {
var service = {
request: request,
};
var error = "";
var currentRequests = [];
return service;
function request(request) {
if (!request.url.includes('api/')) return request;
var deferred = $q.defer();
request.timeout = deferred.promise;
var existingRequests = $filter('filter')(currentRequests, { url: request.url }, true);
existingRequests.forEach(function (request) {
request.promiseObj.resolve('intentional_reject');//how to flag as intentional reject??
});
currentRequests.push({ url: request.url, promiseObj: deferred });
return request;
}
};})();
And here is my angular data service method:
function getBalanceDueSummary(businessPartnerCode) {
return $http({
method: "get",
url: "/api/BusinessPartnerAPI/GetBalanceDueSummary",
params:
{
businessPartnerCode: businessPartnerCode,
}
})
.then(complete)
.catch(failed);
function complete(response) {
return response.data;
}
function failed(error) { //here my cancellation falls into, but i have no data which indicates intentional cancellation
//logService.exception displays a toastr message when error occurrs
logService.exception(error, 'GetBalanceDueSummary');
return $q.reject(error);
}
}
I have done some digging and found the value 'intentional_reject' in object:
error.Config.timeout.$$state.value
function getBalanceDueSummary(businessPartnerCode) {
return $http({
method: "get",
url: "/api/BusinessPartnerAPI/GetBalanceDueSummary",
params:
{
businessPartnerCode: businessPartnerCode,
}
})
.then(complete)
.catch(failed);
function complete(response) {
return response.data;
}
function failed(error) {
if(!(error.Config.timeout.$$state.value &&
error.Config.timeout.$$state.value=='intentional_reject'))
logService.exception(error, 'GetBalanceDueSummary');
return $q.reject(error);
}
}
I doubt this is the best solution for this but I could not set response status manually...
My question is what is the best way to handle errors from http REST calls. Should I use interceptors or decorators? My rest functions look something like this:
queryFunction : function (config) {
var defer = $q.defer();
var config = {};
$http.get(someUrl, config) //or http.put, delete
.then(function (response) {
defer.resolve(response.data);
})
.catch(function (ex) {
defer.reject(ex);
});
return defer.promise;
},
How will the simplest interceptor look?
Here's the code for generic $http ErrorInterceptor:
app.factory('ErrorInterceptor', ['$q', function($q) {
return {
responseError: function(rejection) {
// An error message is shown for all kind of server errors
if (rejection.status == -1) {
//alert('Backend is not working');
//use rejection.data variable
}
return $q.reject(rejection);
}
};
}])
Then it can be included into app config
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('ErrorInterceptor');
})
This code fetches categories and give them to controller.
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function() {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
if ( SuperCategories.length == 0 ) {
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
});
}else {
return $q.when(SuperCategories);
}
}
return SCService;
});
I think code is perfect until there is no error in http request.
My query is how to do error handling (try catch or something like that), in case if server have some issue or may be cgi-script have some issue and not able to server the request.
Angular promises use a method catch for that.
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
});
You should use also finally :
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
}).finally(function() {
// Always executed. Clean up variables, call a callback, etc...
});
Write like
return $http(req).then(function (response) {
//success callback
},
function(){
//Failure callback
});
Use callback methods from controller Like
Controller.js
service.GetSuperCategories(function (data) {console.log('success'},function (error){console.log('error'});
service.js
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function(successMethod,errorMethod) {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
return $http(req).then(successMethod(data),
errorMethod(error));
}
return SCService;
});
You can use the .success and .error methods of $http service, as below
$http(req).success(function(data, status, headers){
// success callback: Enters if status = 200
}).error(function(status, headers){
// error callback: enters otherwise
});