how to detect a server error into a jquery ajax call? - javascript

I use Jquery to parse an json from url: the code is like this:
function fetchdata() {
var statusUrl = '/api/desk/j/';
$.ajax({
url: statusUrl,
dataType: "json",
type: 'post',
success: function(response) {
alert('ok');
},
error: function(xhr, status, error) {
var err = JSON.parse(xhr.responseText);
alert(err.message);
}
});
}
everything works fine, but if the server is not reachable I'm not able to detect it: I tried to do something in error: function, but seems that the code in error is fired only if the json has an error
have you got some ideas?
thank you!

You need to test the statusText from the jQuery textStatus response object. You can take advantage of your browser's developer console to inspect this object. You can expand the properties and methods for your perusal, however you wanna use it. Just click on the returned message of the console.log() to see these properties and methods that you wan't to use for error detection.
function fetchdata() {
var statusUrl = '/api/desk/j/';
$.ajax({
url: statusUrl,
dataType: "json",
type: 'post',
success: function(response) {
alert('ok');
},
error: function(textStatus) {
console.log(textStatus);
console.log(textStatus.statusText, textStatus.status);
}
});
}
fetchdata();

Related

Ajax error getting called instead of success

<script>
function editComment(id) {
var content = $('#Content').val();
var modelData = { 'Id': id, 'Content': content };
$.ajax({
type: 'POST',
dataType: 'json',
url: '#Url.Action("EditC", "Comment")',
data: JSON.stringify({ model: modelData }),
contentType: 'application/json',
success: function () {
alert("YES");
},
error: function () {
alert("Error");
}
});
}
</script>
Here the server is returning 200 OK, but for some reason the error function is getting called. Both type and contentType seem to be correct. Any idea how to fix this?
Edit:
After adding
error: function (xhr, textStatus, error) {
console.log(xhr.responseText);
console.log(xhr.statusText);
console.log(textStatus);
console.log(error);
}
this is what is being logged:
parsererror
parsererror
SyntaxError: Unexpected end of JSON input
at parse (<anonymous>)
at ajaxConvert (jquery-3.4.1.js:9013:19)
at done (jquery-3.4.1.js:9483:15)
at XMLHttpRequest.<anonymous> (jquery-3.4.1.js:9785:9)
Moving to an answer for future readers...
The server is indeed returning a successful response, but an empty successful response:
return new HttpStatusCodeResult(200);
However, the client-side code is expecting valid JSON:
dataType: 'json',
As a result, after the successful response is received, internally the jQuery code attempts to parse that response as JSON and that fails, resulting in triggering the error callback.
Since there's no response body (and in most cases even when there is, as long as the server returns the correct MIME type), you don't need or want to specify a dataType in the jQuery AJAX operation. Simply remove this part:
dataType: 'json',

Access post data from inside ajax error function

I have the below javascript function that takes POST data and sends post request to server using Ajax
function postData(post_data) {
console.log(post_data, "----------->");
var data = post_data;
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataTpe: "json",
success: function (data) {
debugger;
},
error: function (jqXHR, textStatus, errorThrown) {
debugger;
// Can we access the post_data inside this error function ?
},
}
);
};
So what my actual point is, because of some reason the server is sending a 500 response and so the execution point is coming to error: function (jqXHR, textStatus, errorThrown, data), here I want to access post_data to display something to the user.... So can we access the post_data inside ajax error function above?
In case someone looks for a generic way to do this, here is how i did it: In case your handler functions are defined where their scope don't allow you to access some variables, you can add them to the ajax object itself in the function beforeSend. You can then retreive it in the ajax object by using this.
$.ajax({
url:'/dummyUrl',
beforeSend: function(jqXHR, plainObject){
plainObject.originalUrl = 'myValue';
},
success: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
$('#myValue').html(this.originalUrl);
},
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">waiting result</div>
<div id="myValue"></div>
function postData(post_data) {
console.log(post_data, "----------->");
// var data = post_data; // why ?
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataTpe: "json",
success: function (response) { // pay attention to args and vars naming as it makes the code easier to read
// use response
},
error: function (jqXHR, textStatus, errorThrown, data) {
// handle error
console.log(post_data); // and the magic happens
},
}
);
};
Above this issue you were having wrong key "dataType" i have modified it. Secondly, "post_data" is in your scope you can access it without any issue.
function postData(post_data) {
console.log(post_data, "----------->");
// var data = post_data; // why ?
var url = "/super/man/"
$.ajax(
{
type: "POST",
url: url,
data: post_data,
dataType: "json",
success: function (response) { // pay attention to args and vars naming as it makes the code easier to read
// use response
},
error: function ( jqXHR jqXHR, textStatus, errorThrown) {
// post data is in your scope you can easily access it
console.log(post_data); // and the magic happens
},
}
);
};

asp.net ashx handler: can't receive response

Hello everyone and thanks for your time.
Here is my javascript:
$('.sender').click(function (e) {
$.ajax({
type: "POST",
url: "fHandler.ashx",
data: { firstName: 'stack', lastName: 'overflow' },
// DO NOT SET CONTENT TYPE to json
// contentType: "application/json; charset=utf-8",
// DataType needs to stay, otherwise the response object
// will be treated as a single string
dataType: "json",
success: function (response) {
alert('success');
},
error: function (response) {
alert('error: ' + response);
console.log('err: '+response);
}
});
});
And here is the code in my .ashx handler:
public void ProcessRequest(HttpContext context)
{
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");//to fix the allow origin problem
context.Response.ContentType = "text/plain";
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
context.Response.Write(json);
}
public bool IsReusable
{
get
{
return false;
}
}
While the click event is working, my Ajaxrequest doesn't seem to get any response as the alert at success doesn't popup. I've debugged using the browser's network console and it return the expected response but it doesn't seem to reach the success function in the JavaScript code. Any insights or suggestions are welcome. Thanks.
In case you are still interested in the answer, try this before doing the request
var data = { firstName: 'stack', lastName: 'overflow' };
var jsonData = JSON.stringify(data);
and change your AJAX request to
$.ajax({
type: "POST",
url: "fHandler.ashx",
data: jsonData,
dataType: 'json',
contentType: 'application/json; charset-utf-8'
})
.done(function (response) {
// do something nice
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.log("request error");
console.log(textStatus);
console.log(errorThrown);
});
Explanation
You are trying to send the plain data object. You must transform it into a Json string using JSON.stringify(object).
Changing the dataType isn't really a solution but a workaround.
Additional Notes
Also, I think you should use .done() and .fail(). See here for further details.

Check is a Self-Hosted-Service is running or not

I have a Self-Hosted-Service(using WCF) that will run on clients machines. That service is supposed to make request to another server, get the data as XML then it returns to me that data as JSONP. Now i want to check if the service is running or not .. How can i check that ?
In my JS code i use $.getJSON with callback, so i tried to use .fail like this:
$.getJSON("http://localhost:8080/url?callback=?", function () {
alert("success");
}).fail(function () {
alert('fail');
})
but fail function didn't called when the server is not running(on chrome the Type is pending and Status is Failed)
Then i tried to use $.AJAX like this:
$.ajax({
type: 'GET',
dataType: 'jsonp',
url: 'http://localhost:8080/url?callback=?',
success: function (data, textStatus) {
alert('request successful');
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
}
});
I got the same result.
When you make the AJAX request to your localhost and /url? returns weather the other server is up or not, your script won't fail. Because http://localhost/url is online.
I'd make the /url script return JSON array with remoteHostOnline: true or false,
then use:
$.ajax({
type: 'GET',
dataType: 'jsonp',
url: 'http://localhost:8080/url?callback=?',
success: function (data, textStatus) {
if (data.remoteHostOnline == false) {
alert('remote host not online');
}
}
});
You might have to tweak this script I didn't test it but you will understand what's wrong.

How to callback a function on 404 in JSON ajax request with jQuery?

I want to make an Ajax request with response in JSON. So I made this Ajax request:
$.ajax({
url: 'http://my_url',
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},
complete: function(data) {
alert('complete')
}})
This code works good but when my url send me a HTTP code 404, no callbacks are used, even the complete callback.
After research, it's because my dataType is 'json' so 404 return is HTML and the JSON parsing failed. So no callback.
Have you a solution to call a callback function when a 404 is raised ?
EDIT: complete callback don't call is return is 404. If you want an URL wit 404 you can call : http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697 it's with this URL I have my problem.
$.ajax({
url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
dataType: "json",
success: function(data) {
alert('success');
},
error: function(data) {
alert('error');
},
complete: function(xhr, data) {
if (xhr.status != 0)
alert('success');
else
alert('fail');
}
})
With your configuration jQuery uses jsonp to transport the data. This works by dynamically inserting a script element and setting the URL to the specified value. The data returned by the server is then evaluated as JavaScript - usually calling the provided callback. If the server returns a 404, the contents is obviously no JavaScript and the callback is never called. Some browsers support error handlers on the script tag, which are called in these situations. Unfortunately IE doens't support this. The best way to detect an error is to rely on a timeout.
In your case you should specify an additional timeout option, which causes the error handler to be called if the callback wasn't called in time (which would be the case for a 404 response).
$.ajax({
url: 'http://my_url',
timeout: 2000, // 2 seconds timeout
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},
complete: function(data) {
alert('complete')
}
});
Use the statusCode-Option
$.ajax({
url: 'http://my_url',
dataType: "json",
statusCode: {
404: function() {
alert("I could not find the information you requested.");
}
},
success: function(data) {
alert('success');
},
error: function(data) {
alert('error');
},
complete: function(data) {
alert('complete');
}
})
If you want to handle errors when accessing the Twitter API with Javascript and jsonp you need to include the parameter suppress_response_codes in your request. This makes all responses from the Twitter API respond with a 200 OK response and include a error. Then you need to check if the response includes the error parameter or not.
$.ajax({
url: "https://api.twitter.com/1/users/show.json",
dataType: 'jsonp',
jsonp: "callback",
data: {
screen_name: "simongate1337",
suppress_response_codes: true // <- Important part
},
success: function(data) {
if(data.error) {
console.log("ERROR: "+data.error);
} else {
console.log("Success, got user " + data.screen_name);
}
}
});
Do not you think that the problem is not with the dataType but with cross-domain requests that you are not allowed to make?
The code below works as expected when you request data from the same domain and does not when you are making cross-domain requests:
function handle404(xhr){
alert('404 not found');
}
function handleError(xhr, status, exc) {
// 0 for cross-domain requests in FF and security exception in IE
alert(xhr.status);
switch (xhr.status) {
case 404:
handle404(xhr);
break;
}
}
function dumbRequest() {
var url = 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
url = 'http://twitter.com/';
url = '/mydata.json';
// url = 'mydata.json';
$.ajax(
{url: url,
dataType: 'json',
error: handleError}
);
}
Is it simply because the dataType is set to "json"? If so, try changing it to text and evaluate the JSON yourself:
$.ajax({
url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
dataType: 'text',
success: function(data, status, xmlHttp) {
try {
data = eval('(' + data + ')');
alert('success');
} catch (e) {
alert('json parse error');
}
},
error: function(xmlHttp, status, error) {
alert('error');
},
complete: function(xmlHttp, status) {
alert('complete');
}
});
Are you aware that even though the HTTP status is 404, the actual body is valid JSON? For instance, this link has the following JSON:
jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})
As such, you should check if your data has the error property within your normal callback function.
UPDATE: apparently, even though the actual content of the page is valid JSON, the browser (I checked in Firefox) is not executing it, most likely because it is a 404. Because jQuery has to add a script element (because of the cross-domain issue), its JSONP wrapper is never called, and as a consequence, neither are your callbacks.
So, in short, I don't think there is a way to deal with this without manually adding that script element and checking if your pre-defined callback function has been called afterwards.
Just faced the same issue, and saw another question mentioned that jQuery-JSONP (jQuery Plugin) supports catching 404 errors or as they describe: "error recovery in case of network failure or ill-formed JSON responses"
And it works perfect :)
Here is my (simplified) code for fetching details about a YouTube video via JSONP:
$.jsonp(
{
url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
callbackParameter: "callback",
data:
{
alt: "jsonc-in-script",
v: "2"
},
success: function(json, textStatus)
{
console.log("WEEEEEEEE!");
},
error: function(xOptions, textStatus)
{
console.error(arguments);
}
});
Here's how I deal with this. I check the returned data for errors before trying to use it. What is shown below is just a sample that you could extend to more closely match your requirements. This also considers session time outs and other scenarios...
My initial call:
$.ajax({ type: 'POST',
url: '../doSomething',
data: 'my data',
success: function(data) {
if (HasErrors(data)) return;
var info = eval('(' + data + ')');
// do what you want with the info object
},
error: function(xmlHttpRequest) {
ReportFailure(xmlHttpRequest);
}
});
And the two helper functions:
function HasErrors(data) {
if (data.search(/login\.aspx/i) != -1) {
// timed out and being redirected to login page!
top.location.href = '../login.aspx';
return true;
}
if (data.search(/Internal Server Error/) != -1) {
ShowStatusFailed('Server Error.');
return true;
}
if (data.search(/Error.aspx/) != -1) {
// being redirected to site error reporting page...
ShowStatusFailed('Server Error. Please try again.');
return true;
}
return false;
}
and
function ReportFailure(msg) {
var text;
if (typeof msg == 'string') {
text = msg;
}
else if (typeof msg.statusText == 'string') {
if (msg.status == 200) {
text = msg.responseText;
}
else {
text = '(' + msg.status + ') ' + msg.statusText + ': ';
// use the Title from the error response if possible
var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
if (matches != null)
{ text = text + matches[1]; }
else
{ text = text + msg.responseText; }
}
}
// do something in your page to show the "text" error message
$('#statusDisplay')
.html('<span class="ui-icon ui-icon-alert"></span>' + text)
.addClass('StatusError');
}
Following solution is working fine for me :)
$.ajax({
url: 'http://my_url',
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},complete: function(xhr, data) {
if(data==="parsererror"){
alert('404');
}
}
});

Categories

Resources