Handling error in ajax request in Select2 - jquery-select2-4

I need to detect if user session is gone when expanding Select2 combobox. When that condition occurs, response is redirected to login page.
The Select2 is populated using an ajax call, so I have added this to the "ajax" parameter:
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
});
return $request;
}
The problem is that the error reported is not in XHR format (in order to detect 401 HTTP code) but an error telling "SyntaxError: Unexpected end of JSON input".
When seeing the response using Chrome developer tools, I do see that the response was in XHR format with 401 HTTP code but Select2 transforms it in some way.
Is there a way to solve this?
Regards
Jaime

ajax: {
// ...
error: function (jqXHR, status, error) {
console.log(error + ": " + jqXHR.responseText);
return { results: [] }; // Return dataset to load after error
}
}

Related

$http error handling in AngularJS

$http in my AngularJS project not able to recognize 40X(401,403,405...) errors on iOS.
I am using 1.2.10 AngularJS version and Cordova version 3.4.0.
Below is the code I am using:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials,successCallback,errorCallback){
$http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
successCallback(response.data);
console.log("Success------"+JSON.stringify(response))
},function(data, status, headers, config){
errorCallback(data);
console.log("Error------"+JSON.stringify(data)+" "+status)
})
}
}
});
hello.loginUser($rootScope.encodedUserCredencials,function(persons) {
// success handler
}, function(data) {
// error handler
console.log(data.status+"===="+status)
});
data.status is returning 0 and status returns undefined.
Please help me to resolve this issue.
Tried to include the domain in whitelist on IOS.But no solution :( It still gives the same response.
But the same code works absolutely fine in Android.
Please help me to resolve this issue.
Thanks in advance :)
So you r using the $http from angular. Do you use the error callback or the second function in the then callback ?
Example
$http.get("someUrl")
.success(function(response){}) // if http code == 200
.error(function(response){}) // else
Or with then, that can take 2 functions. The first is the onSuccess, the second the onError function.
$http.get("someUrl")
.then(function(response){
// if http code == 200
},
function(response){
// else
});
The response parameter does also contain the error codes.
Consider using a $httpInterceptor to handle all errorcodes at the same place, instead handling them in every http callback.
UPDATE:
It seems, that the angular doc is incomplete/wrong for the success callback.
It doesnt pass 4 parameter there. It does pass a response object that contains all the information about request+response and the passed data.
Update to the edit:
Dont write callbacks by yourself. Use angular promises:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials){
return $http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
return response.data;
},function(response){
return response;
});
}
}
});
hello.loginUser($rootScope.encodedUserCredencials)
.then(function(persons) { // success handler
}, function(data) { // error handler
console.log(data);
});
Try this and tell me if the console.log logs something.
I had exactly the same problem. Cordova app, angular js, IPhone and 401 requests are not received in angular js http interceptor. They work fine on android devices.
My finding was that IPhone browser is handling those at a higher lever and trying to use WWW-Authenticate information to do authentication. This is why the response does not get to angular.
The only solution I found, was to change my service to return 400 instead of 401 in case of an api request. In this case I return 400 with an error message that I handle on client side.
I hope this helps.
My issue with the 403 status code was that my backend returned a response with status 403 but the body of a response did not contain a JSON string. It contained just a string - Authentication Failed.
The rejection variable was an object Error.
I encoded the body and the rejection variable contains a valid response error object.
To handle HTTP errors I use interceptors.
$httpProvider.interceptors.push(function($q, $location, redirect, HTTP_CODES) {
return {
'responseError': function(rejection) {
if (rejection.status === HTTP_CODES.FORBIDDEN) {
redirect('/login', $location.url());
}
return $q.reject(rejection);
}
};
});

Jquery (2) not calling AJAX Success call

I've the following generic PostTo method which can be used to post data to an ASP.NET MVc Controller, without the need for repetitive mark-up, I'm pretty sure it was working at one point, but for some reason, the success callback (any of it) doesn't get called.
Any thoughts? Everything looks right, and the server is responding with a valid 200 OK response.
It is however, an empty response. I tried a different (and empty) dataType value, but nothing changed.
function PostTo(controller, action, data, successCallback) {
$.ajax({
url: Settings.HostPath + controller + "/" + action,
type: "POST",
cache: false,
dataType: "json",
data: data,
success: function (data, textStatus, jqXHR) {
if (typeof (successCallback) != "undefined")
successCallback.call(this, data);
}
});
}
ajax method in your script, excepts json data from the server, but as you told in comments, your actions returns nothing (i thinks it's returns EmptyResult).
So, add any json result in your action:
public ActionResult Test()
{
return Json(new {Success = true});
}

Passing data to Ajax Error block

I have a controller with the following catch statement which returns a partial view and the error to display.
catch (Exception ex)
{
return PartialView("ErrorPartial", new ErrorModel(ex));
}
This controller is being invoked through an Ajax call like this...
$('#myID').ajaxSubmit({
url: buildUrl('MyController'),
beforeSubmit: function () {
toggleOverlay(true, 'Saving...');
},
success: function (responseText, statusText, xhr) {
successSave(responseText, statusText, xhr)
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
If the exception is caught, then the code falls into the error block however I'm unable to pass the partial view data into this.
Is there anyway I can pass the partial data into the error block? If not, could you possibly recommend an alternative?
Thanks :)
You're probably looking for jqXHR.responseText. However, it's not very clear for me why does your js code fail into the error block - you've handled the exception so ajax request should be considered as successfull and success function should be triggered. Here's my C# code which leads to ajax request fail but passes the data along with the error.
Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
return PartialView("SomePartialView", model);

MVC rest API status code 500 with JSON return

I am developing a rest API on MVC3.
Whenever there is a problem with validation, I want to throw 500 + json that describes the error (the json can be the list of unvalidated fields).
The problem is that the json returns inside html that holds the entire HttpExeption (Server Error in '/' Application.)
If I put filterContext.ExceptionHandled = true; the message goes out clean, but the client can't see the 500 error on his side.
This case: https://stackoverflow.com/a/4707762/936651 actually the html and gives clean json to the client, but also removes the 500 error.
You could set the status code to 500 inside the custom error handler you have seen here:
filterContext.RequestContext.HttpContext.Response.StatusCode = 500;
and on the client:
$.ajax({
url: '/home/foo',
success: function (result) {
alert('success');
},
error: function (jqXHR, textStatus, errorThrown) {
var json = $.parseJSON(jqXHR.responseText);
// TODO: do something with the json that was returned from the server
}
});

jQuery JsTree and JSON error handling

I am using MVC to pass JSON data to JsTree and show a hierarchical view of information.
Everything is working just fine, however, there are times when the user does not have access the the data or for some reason the MVC action throws an exception:
In these cases, the action passes a JSON error message and sets the HttpStatusCode to NotAccepted or InternalServerError.
However the jsTree's sinner keeps spinning and I don't seem to find a way to make it stop and show the error message.
Has anyone solved this issue before? How can one does error handling when using JsTree's JSON data plugin?
UPDATE:
I figured out how to capture the error:
$("#jstree1").jstree({
"json_data": {
"ajax": {
"url": serviceUrl,
"data": function (n) {
return { pid: n.attr ? n.attr("id") : "" };
},
"error": function (x, s, r) { var err = $.parseJSON(x.responseText); if (err!="") { alert(err); } }
}
}
It seems that JsTree does get the MVC http statusCode and the error, now I need to figure out how to tell the JsTree to stop waiting and remove the spinner image!
I am also looking for a good way of showing the error in JsTree, or should I manage the error message outside of it?
I've solved this problem.
Just a note- the code example above for handling ajax call errors is incorrect, please see a complete example below:
$('#YourTree').jstree({
"json_data": {
"ajax": {
"url": "/Controller/Action",
"data": function () {
return { Parameter1: "Value1", Parameter2: "Value2" }
},
"type": "POST",
"dataType": "json",
"error": function (jqXHR, textStatus, errorThrown) { $('#YourTree').html("<h3>There was an error while loading data for this tree</h3><p>" + jqXHR.responseText + "</p>"); }
}
}
});
And in the actual action, you need to set the http response status code to 1 and write the error. e.g.
Response.StatusCode = 1
Response.Write("Error you want to go into jqXHR.responseText here");
Enjoy :)
Maybe you should look into handling this error a layer above the .jstree. Maybe by handling the window.onerror event you can achieve this. In here you could call a function that will rebuild the tree or something? Be sure to include this script as the first one in your page.
<script type="text/javascript">
window.onerror = function(x, s, r){
alert('An error has occurred!')
}
</script>

Resources