How can I handle an HTTP error, e.g. 500, when using the AngularJS "http get then" construct (promises)?
$http.get(url).then(
function(response) {
console.log('get',response)
}
)
Problem is, for any non 200 HTTP response, the inner function is not called.
You need to add an additional parameter:
$http.get(url).then(
function(response) {
console.log('get',response)
},
function(data) {
// Handle error here
})
You can make this bit more cleaner by using:
$http.get(url)
.then(function (response) {
console.log('get',response)
})
.catch(function (data) {
// Handle error here
});
Similar to #this.lau_ answer, different approach.
https://docs.angularjs.org/api/ng/service/$http
$http.get(url).success(successCallback).error(errorCallback);
Replace successCallback and errorCallback with your functions.
Edit: Laurent's answer is more correct considering he is using then. Yet I'm leaving this here as an alternative for the folks who will visit this question.
If you want to handle server errors globally, you may want to register an interceptor service for $httpProvider:
$httpProvider.interceptors.push(function ($q) {
return {
'responseError': function (rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
});
Docs: http://docs.angularjs.org/api/ng.$http
Try this
function sendRequest(method, url, payload, done){
var datatype = (method === "JSONP")? "jsonp" : "json";
$http({
method: method,
url: url,
dataType: datatype,
data: payload || {},
cache: true,
timeout: 1000 * 60 * 10
}).then(
function(res){
done(null, res.data); // server response
},
function(res){
responseHandler(res, done);
}
);
}
function responseHandler(res, done){
switch(res.status){
default: done(res.status + ": " + res.statusText);
}
}
I could not really work with the above. So this might help someone.
$http.get(url)
.then(
function(response) {
console.log('get',response)
}
).catch(
function(response) {
console.log('return code: ' + response.status);
}
)
See also the $http response parameter.
Related
I need to be able to differentiate between a 400 and 500 range error code for different flows in our application.
Lets say I have 3 rest calls,
First will return 200,
second will return 401,
and third will return 502
I started using aurelia-http-client, which is where I first noticed that I was getting the http error code = 0 in the promise`s reject callback.
Update: Using aurelia-fetch-client returns only a string as a error response, thus wasn't an option either.
I then tried using an ajax call and a basicXMLHttpRequest, which yielded the same result. For 200 range, I got the codes, but anything above, I received a statusCode of 0.
Update: I am running Version 63.0.3239.132 of Chrome if it makes a difference.
What I've tried:
I've tried about 5 different variations for fetch.
fetch(url, {
method: requestMessage.method,
headers,
body: JSON.stringify(content)
})
.then((result) => {
resolve(result)
})
.catch((error) => {
reject(error);
});
Outputs a string error
Using aurelia-http-client
this.httpClient.createRequest(url)
.asPut()
.withContent(params)
.send()
.then((response) => {
resolve(response);
},
(error) => {
reject(error);
});
- StatusCode is always 0 for errors
Also (This just builds up a dynamic XmlHttpRequest):
private retryRequest(): void {
var xhr = this.setupXhr();
xhr.onreadystatechange = () => this.stateChange(xhr);
setTimeout(() => {
xhr.send(JSON.stringify(this.content));
}, 1000);
}
private setupXhr(): XMLHttpRequest {
var xhr = new XMLHttpRequest();
xhr.open(this.method, this.url, true);
xhr = this.addHeaders(xhr);
return xhr;
}
private addHeaders(xhr: XMLHttpRequest): XMLHttpRequest {
for (let key in this.headers) {
if (this.headers.hasOwnProperty(key)) {
xhr.setRequestHeader(this.headers[key].key, this.headers[key].value);
}
}
return xhr;
}
private stateChange(xhr: XMLHttpRequest): void {
logger.debug(' ::>> xhr = ', xhr);
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 400) {
this.resolve(JSON.parse(xhr.response));
} else if (xhr.status >= 500) {
this.retryRequest();
} else {
// this.retryRequest();
this.reject(xhr.response); // call after a # of fails for this ???
}
}
}
Which only returns the 200 range http status codes
Also:
$.ajax({
type: requestMessage.method,
url,
data: JSON.stringify(content),
headers,
success: (data) => {
logger.debug(' ::>> rest call was a success ', data);
resolve(data);
},
statusCode: {
502: (jqXHR) => {
logger.debug(' ::>> received 502 ');
var retryAfter = jqXHR.getResponseHeader('Retry-After');
retryAfter = parseInt(retryAfter, 10);
if (!retryAfter) { retryAfter = 5 };
setTimeout(query, retryAfter * 1000);
}
}
});
- Which never gets to the 502 callback. I've tried other status codes as well
Is there a way of getting the error codes which I might be missing? Any help appreciated
I had similar requirement and have implemented this using following code
$.ajax({
type: "POST",
url: urlAjax,
dataType: 'json',
headers: headerValue,
data: _dataValue,
crossDomain: true,
beforeSend: function () {
//any operation
},
complete: function () {
// any after operation
},
success: function (data) {
// All 2XX will reach here
},
error: function (jqXHR, textStatus, error) {
var Check = JSON.parse(jqXHR['responseText']);
// In above array you will get whole error response
}
}).done(function (rs, textStatus, xhr) {
// on finished
});
In jqXHR, textstatus and errror params you will receive all the information about errors and codes related to it.
Hope that helps.
Found the issue:
I initially thought Harshal Bulsara's was what resolved my issue. It is a nice implementation, but I found the actual issue.
I found that our nginx response didn't send the required headers.
By adding the Access-Control-Allow-Origin header, I received the statusCode.
If i have one API server then the API is send ajax data with JSON format :
{"status":304,"message":"Cannot delete data where PK is empty or > 1"}
how to AngularJS $http post call the status and message to alert bootbox?
here my AngularJS $http post
$http({
method: "POST",
url: apiUrl('disable_assethw'),
data: {
id: id
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
if(response.status == 304) {
bootbox.alert("Something went error.." + response.data.message);
} else {
$scope.getAssetHW();
}
}, function errorCallback(response) {
bootbox.alert("Something went error.." + response.status);
});
thanks for advise.
When doing a POST request with JavaScript objects as data, use the AngularJS default content type (which is automatically set to application/json). The $http service also automatically encodes JavaScript objects as JSON strings.
Only response with status in the range 200-299 are processed by the success handler. Status outside the range are processed by the rejection handler:
$http({
method: "POST",
url: apiUrl('disable_assethw'),
data: {
id: id
},
headers: {
̶'̶C̶o̶n̶t̶e̶n̶t̶-̶T̶y̶p̶e̶'̶:̶ ̶'̶a̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶/̶x̶-̶w̶w̶w̶-̶f̶o̶r̶m̶-̶u̶r̶l̶e̶n̶c̶o̶d̶e̶d̶'̶
}
}).then(function successCallback(response) {
̶i̶f̶(̶r̶e̶s̶p̶o̶n̶s̶e̶.̶s̶t̶a̶t̶u̶s̶ ̶=̶=̶ ̶3̶0̶4̶)̶ ̶{̶
̶b̶o̶o̶t̶b̶o̶x̶.̶a̶l̶e̶r̶t̶(̶"̶S̶o̶m̶e̶t̶h̶i̶n̶g̶ ̶w̶e̶n̶t̶ ̶e̶r̶r̶o̶r̶.̶.̶"̶ ̶+̶ ̶r̶e̶s̶p̶o̶n̶s̶e̶.̶d̶a̶t̶a̶.̶m̶e̶s̶s̶a̶g̶e̶)̶;̶
̶}̶ ̶e̶l̶s̶e̶ ̶{̶
$scope.getAssetHW();
̶}̶
}, function errorCallback(response) {
//HANDLE 304 status HERE
if(response.status == 304) {
bootbox.alert("Something went error.." + response.data.message);
} else {
bootbox.alert("Something went error.." + response.status);
};
});
From the Docs:
A response status code between 200 and 299 is considered a success status and will result in the success callback being called. Any response status code outside of that range is considered an error status and will result in the error callback being called. Also, status codes less than -1 are normalized to zero. -1 usually means the request was aborted.
— AngularJS $http Service API Reference
Note: A status of -1 usually indicates the browser rejected the request with a CORS problem that violates same-origin policy.
you said it is json response and you used: application/x-www-form-urlencoded , which is wrong.
The best practice to handle rest/api call is:
Create 1 common/general function which is accessible in whole application which will manage your post api call(add api response to callback):
postAPICall(url, body, data) {
let headers = new Headers({'Content-Type': 'application/json'});
this.http
.post(url,
body, {
headers: headers
})
.map(
response => response.json())
.subscribe(
response => {
data(response);
},
err => data(this.handleError(err)); //handle error here
);
}
call this function wherever required(in component or service):
var yourJSONBody = {
"param-1": "",
"param-2": "",
//....
}
}
this.myCommonService.postAPICall("localhost:8080/app/", yourJSONBody, data => {
if (data.status == "304") {
//do stuff
//this.msgs.push({severity: 'error', detail: data.message});
}
else {
//do stuff
}
});
error handler function:
private handleError(error: any) {
let description = 'There was an error: ' + error.status;
let errors = {
errorcode: error.status,
errorstatus: error.statusText,
errordescription: description
};
return errors;
}
I have one request.post call and another function.Where I need to pass the response of restcall as paramaters to the function.
The current issue which Iam facing here is that the function is getting called even before i get response from the rest call and null values are getting passed.I know that we need to use some callabcks for this issue.But I dont know how to do it.can someone help.
app.post('/verifycreds',function(req,res) {
var reqdata = req.body;
var data = {};
data.custid = reqdata.custid;
request.post({
url:'https://database.mybluemix.net/verifycredentials',
headers:{
'Content-Type':'application/json'
},
body:data,
json:true
}, function(err,response) {
verifycreds(response.body);
});
function verifycreds(data) {
if((datareq.customerid === data.customerid ) && (datareq.password == data.password)){
res.send("valid");
} else {
res.send("invalid");
}
}
So how can I call verifycreds function only after I get response from the request .post call..Any help!
Your callback is valid, the problem in callback parameters. It should be defined with three parameters:
error
response
body
So correct code is:
request.post({
url: 'https://database.mybluemix.net/verifycredentials',
headers: {
'Content-Type': 'application/json'
},
body: data,
json: true
}, function(err, res, body) {
// TODO: process possible errors
// if (err) { ...
verifycreds(body);
});
I have a bunch of http requests like this:
$q.all([$http({
method: 'POST',
url: urlOne,
headers: {Authorization: "Token " + jqToken}
}), $http({
method: 'POST',
url: urlTwo,
headers: {Authorization: "Token " + jqToken}
})])
.then(function (results) {
//do stuff
});
However urlOne and urlTwo (and a bunch of others) may under some conditions return 403. In this case everything just freezes and then() function is never executed. How can I handle 403 responses?
Thanks.
It sounds like you need to handle errors.
$q.all([...])
.then(
function (results) {
// Handle success
}, function (err) {
// Handle errors
});
Re-asked question with real code VS sudo code at
Having problems with some code on Parse.com's Cloud Code
/*
What am I doing wrong here?
I didn't want to re-write all my code to work with Parse.Cloud.run so I decided to make a function that would do that for me.
Error Message:
Update failed with Could not load triggers. The error was TypeError: Object # has no method 'request'
*/
Parse.Cloud.define("httpx", function(request, response) {
Parse.Cloud.httpRequest({
url: request.params.url,
method: request.params.method,
headers: request.params.headers
}, {
success: function(httpResponse) {
response.success(httpResponse);
},
error: function(httpResponse) {
response.error(httpResponse);
}
});
});
function sendRequest(path, method, callback) {
if (!initialized) {
throw 'not initialized, call initialize(username, password) first before calling the API';
}
// Allows for only 2 paramiters to be passed if no method passed.
if (typeof method == 'function') {
callback = method;
method = 'GET';
}
var type = (useHttps) ? 'http://' : 'https://';
////////////////////////////////////////
var request = Parse.Cloud.run("httpx", {
url: type + 'rest.website.com/' + path,
method: method,
headers: headers
}, {
success: function(httpResponse) {
if (callback) {
callback(httpResponse.text);
}
response.success(httpResponse.text);
},
error: function(httpResponse) {
callback(httpResponse.status);
response.error('Request failed with response code ' + httpResponse.status);
}
});
//////////////////////////////////////////
}
response.success(httpResponse.text);
where do you define response object?