See the below code,I am trying to handle the error which is returned by the twitter api call. Remember Jquery do not handle jsonp datatypes and hence the timeout , the below code will obviously throw an error for a non existent twitter ID. I want to catch that error in my req.error method and show it to the user. But apparently , the error is hidden and does come to console.log('Oh noes!'+msg.error); This has surely something to do with the jquery handling jsonp type data. Has anyone encountered the same ? Any solutions ?
function findUserInfo(){
var req = $.ajax({
url: "https://twitter.com/users/show.json?id=neverexistID",
dataType : "jsonp",
timeout : 10000
});
req.success(function(msg) {
console.log('Yes! Success!'+msg);
});
req.error(function(msg) {
console.log('Oh noes!'+msg.error);
});
}
Answer:
jsonp calls are special and the errors thrown is usually hidden,and thats why I couldn't handle the error situation,the below plugin handles the situation well and solved my issue.
jsonp plugincode.google.com/p/jquery-jsonp
There is a workaround for your problem, change your url call to:
url: "https://twitter.com/users/show.json?suppress_response_codes&id=neverexistID",
From the Twitter documentation
suppress_response_codes: If this parameter is present, all responses
will be returned with a 200 OK status code - even errors. This
parameter exists to accommodate Flash and JavaScript applications
running in browsers that intercept all non-200 responses. If used,
it’s then the job of the client to determine error states by parsing
the response body. Use with caution, as those error messages may
change.
Related
I have looked at the following thread
jQuery Ajax - Status Code 0?
However I could not find a definitive answer and I am having serious trouble trying to find the source of my issue so I am posting here in the hopes that someone can point me in the right direction.
In my code I am performing an Angular HTTP post which just sends basic JSON data, then within the on success callback I am using AJAX to upload files to the same server. (I know I should not be using jQuery and Angular however I can't change this for the moment)
It looks something like this
var deferred = $q.defer()
// first post
$http.post(url,payload,{params: params, headers: headers)
.then(function(response) {
uploadFiles(response,deferred);
// I am also sending google analytics events here
}, function(error) {
// do error stuff
}
return deferred.promise;
// upload files function
function uploadFiles(response,deferred){
$ajax({
type: 'POST',
processData: false,
contentType: false,
data: data // this new FormData() with files appended to it,
url: 'the-endpoint-for-the-upload',
dataType: 'json',
success: function(data) {
// do success stuff here
deferred.resolve(data);
},
error: function(jqXHR, textStatus, errorThrown) {
var message = {};
if (jqXHR.status === 0) {
message.jqXHRStatusIsZero = "true";
}
if (jqXHR.readyState === 0) {
message.jqXHRReadyStateIsZero = "true";
}
if (jqXHR.status === '') {
message.jqXHRStatusIsEmptyString = "true";
}
if (jqXHR.status) {
message.jqXHRStatus = jqXHR.status;
}
if (jqXHR.readyState) {
message.jqXHRReadyState = jqXHR.readyState;
}
if (jqXHR.responseText) {
message.jqXHR = jqXHR.responseText;
}
if (textStatus) {
message.textStatus = textStatus;
}
if (errorThrown) {
message.errorThrown = errorThrown;
}
message.error = 'HTTP file upload failed';
logError(message);
deferred.resolve(message);
}
}
})
}
Not my exact code but almost the exact same.
The issue is that is works almost all of the time, but maybe three or four in every few hundred will fail. By fail I mean the error handler function is called on the file upload function and the files are not uploaded.
I get jqXHRStatus 0 and jqXHRReadyState 0 when this occurs.
The only way I am able to replicate the issue is by hitting the refresh on the browser when the request is being processed, however users have advised they are not doing this (although have to 100% confirm this)
Is there perhaps a serious flaw in my code which I am not seeing? Maybe passing deferred variable around isn't good practice? Or another way the ajax request is being cancelled that I am not considering? Could sending google analytics events at the same time be interfering?
Any advice would be great and please let me know if you would like more information on the issue.
This means, the request has been canceled.
There could be many different reasons for that, but be aware: this could be also due to a browser bug or issue - so i believe (IMHO) there is no way to prevent this kind of issues.
Think for example, you get a 503 (Service Unavailable) response. What you would do in such a case? This is also a sporadic and not predictable issue. Just live with that, and try to repost your data.
Without reinventing the wheel, I suggest you to implement:
Retrying ajax calls using the deferred api
My guess is that your code is executing before it actually gets back from the call. I.e. the call goes back and nothing was returned and it gives a 0 error. This would make sense as the error is variable. Most of the time it would return fine because the backend executed fast enough but sometimes it wouldn't because it took especially long or something else happened etc. Javascript doesn't ever REALLY stop execution. It says it does but especially passing between angular and jquery with multiple ajax requests it wouldn't be surprising if it was executing the second ajax call before it actually completed your angular post. That's why a refresh would replicate the error because it's would clear your variables.
Some things you can do to test this:
On the backend make a timer that goes for a few seconds before it returns anything. This will probably make your code fail more consistently.
Set breakpoints and see when they are being hit and the values they contain in the javascript.
Good luck!
I'm writing a jQuery interface to use a couple of OData services created in SAP. The services is working ok, and are also being used by some other applications.
I've already searched and I'm mostly come across people who are saying it's a cross domain issue. The first thing I tried was to plain and simply do a cross domain ajax call:
$.ajax({
url : 'http://saphostname:8000/sap/opu/odata/sap/entityset/?$format=json',
crossDomain : true,
xhrFields {
withCredentials : true,
}
// .. success, statusCodes, whatever ..
})
The responses that came from this call were 200, and if I viewed the content in the developer tools I saw my json message as I would expect it to be in there, but none of my callback functions were being triggered.
Upon searching more, somebody suggested using $.getJSON(). This didn't work either. The error that kept coming back was 401, so I assumed it was a cross domain issue.
The last thing I stumbled upon was JSONP. The response is coming back with an OK status code, and once again if I view the body content I see my json string as I would expect it. The only problem is my browser says there is a syntax error in the response text.
All of my search results have brought up issues regarding cross domain requests, and errors resulting there-in. Maybe it is the issue, but because I'm getting the results back that I would expect in the responses, I'd have to assume that connectivity is no problem.
tl;dr: ajax cross-domain requests are successful but don't trigger callback functions and jsonp gives me a syntax error. I'm not sure where to keep looking.
You are trying to do a JSONP request to a JSON service. The way that the response is handled for a JSONP request is that it is executed, but executing a JSON response only evaluates it and discards it.
The crossDomain property only causes the request to act like a cross domain request, i.e. using JSONP, regardless if it's actually to a different domain or not.
You should specify dataType: 'json' in the properties, to keep it from using JSONP.
Alternatively, if the service also supports JSONP, you could change $format=json in the URL to $format=jsonp, and specify dataType: 'jsonp' in the properties.
Edit:
Another thing that you can try is to use a proxy that turns a JSONP request to a JSON request. I have set up such a proxy that you can use to test if you can get the right response:
$.get(
"http://jsonp.guffa.com/Proxy.ashx?url=" + escapeURIComponent("saphostname:8000/sap/opu/odata/sap/entityset/?$format=json"),
function(data) {
console.log(data);
},
"jsonp"
);
I already had a problem like this before and what helped me to solve the problem was using callbacks like these:
// Assign handlers immediately after making the request,
// and remember the jqXHR object for this request
var jqxhr = $.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
// Perform other work here ...
// Set another completion function for the request above
jqxhr.always(function() {
alert( "second complete" );
});
Now you can see which one is being triggered and debug the problem.
After refering this stack link Ajax response not calling success:function() when using jQuery 1.8.3 am wondering why if I uncomment the datatype line the success function is not invoked.I can understand that dataType =JSON is not calling success function.Could some one help me out ?
function doAjaxCall(methodType,Url,params,requestType,callBackFunction)
{
if(validate.variable(Url) && validate.variable(params))
{
$.ajax({
type : methodType,
url : Url,
// dataType : 'JSON', //if i uncomment i am not getting the response under success
data : params,
success : function(data)
{
console.log(data);
callBackFunction(data);
}
});
}
}
function callBackFunctiontest(data)
{
console.log('callBackFunctiontest : ' +data);
}
doAjaxCall('GET','/getData?accountNumber=9840100672&oid=d11c9f66-4c55-4855-a99e-580ba8ef8d61','noparams','application/JSON',callBackFunctiontest);
If it's not passing in success function, put an error function. This way you'll be able to see the error and understand what's going on.
You can also open the developer console and have a look at the 'network' panel.
Assuming you're calling callBackFunctiontest which should then be calling doAjaxCall.
You're trying to use data when there is no variable named data in scope. It will throw an undefined exception and doAjaxCall will not get executed. So your AJAX request will never get sent.
Try getting rid of the console.log('callBackFunctionTest : ' +data);, or pass it a value for data.
I am using Express JS web framework and NodeJS, both latest versions - 4.x.x.
Issue #1 - Not all of my POST ajax calls were being sent to my NodeJS server code.
How I found this is by trying to POST using Postman. All POSTMAN call requests were received by the server code but not the Express client requests. I checked by printing the console.log server debug statements to compare the findings between POSTMAN & Express Client.
Issue #2 - I was never receiving any response message from the server even though the server responded with a status 200 OK.
For both the issues, I made a few changes, which I believe will help others.
In the ajax call, I added e.preventDefault(); where 'e' is the event which is triggered via #click/#onclick.
Within ajax function call, I added the parameter dataType: 'json'.
In the NodeJS server code, index.js, I replaced res.send(req.body.search_data); with res.json(req.body.search_data);
P.S. - e.preventDefault() was actually built for a different purpose but it helped because it prevents a link from following the URL which is what solved the above issues.
When doing AJAX through Dojo we can pass two callbacks, one to execute after a successfull request and one to execute after an error:
dojo.xhr("GET",{
url: myURL,
content: messageContents,
load: function(returnData, ioArgs){
//This is called on success
},
error: function(returnData, ioArgs){
//This is called on failure
}
});
I couldn't find in the documentation what is defined as an error. I'd guess anything with a return code >= 400 but I'm not sure.
Generally speaking, an unsuccessful HTTP response code. The determination is made by calling dojo._isDocumentOk which as you'll see basically accepts 2xx and 304 plus some browser-quirk stuff.
I'm using jQuery.getJSON() on a URL (different domain) which may not exist. Is there a way for me to catch the error "Failed to load resource"? It seems that try/catch doesn't work because of the asynchronous nature of this call.
I can't use jQuery.ajax()'s "error:" either. From the documetation:
Note: This handler is not called for cross-domain script and JSONP requests.
If you have an idea of the worst case delay of a successful result returning from the remote service, you can use a timeout mechanism to determine if there was an error or not.
var cbSuccess = false;
$.ajax({
url: 'http://example.com/.../service.php?callback=?',
type: 'get',
dataType: 'json',
success: function(data) {
cbSuccess = true;
}
});
setTimeout(function(){
if(!cbSuccess) { alert("failed"); }
}, 2000); // assuming 2sec is the max wait time for results
This works:
j.ajaxSetup({
"error":function(xhr, ajaxOptions, thrownError) {
console.log(thrownError);
}});
Deferred objects (new in jQuery 1.5) sound like exactly what you're looking for:
jQuery.Deferred, introduced in version 1.5, is a chainable utility object that can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
http://api.jquery.com/category/deferred-object/
EDIT:
The following code works fine for me:
function jsonError(){
$("#test").text("error");
}
$.getJSON("json.php",function(data){
$("#test").text(data.a);
}).fail(jsonError);
json.php looks like this:
print '{"a":"1"}';
The error function fires for me if the path to json.php is incorrect or if the JSON is malformed. For example:
print '{xxx"a":"1"}';
What your complaining about is a client-side error saying that you tried to download a resource from the server.
This is build into the browser and it allows your browser to tell the client or the developers that the downloading of a resource from the internet failed. This has nothing to do with JavaScript and is a more low level error thrown on the HTTP that is caught by the browser.
If you want any hope of catching it your going to need to drop 3rd party ajax libraries and deal with the XMLHTTPRequest object on a much lower level, even then I doubt you can do anything about it.
Basically when you see this error then find out what object your trying to get that doesn't exist or couldn't be accessed. Then either stop accessing it or make it accessible.