Issue Parsing JSON Response - javascript

I'm using AJAX/JQuery to call a WCF service. I have some .NET try/catch error-handling on the service-side that checks to see if the user has timed out, and if they have then I pass back a JSON-converted message which I then parse out on the client-end using parseJSON and use it to re-direct the user back a login page.
This is all working great, but I just got a different type of error returned from the service that WASN'T in JSON format (it was XML) so the error-handling function got a javascript error on the client side when it tried to parse the reply. The error was in the jquery.min.js file, and was an 'Invalid character' error.
My question (finally), is there a better way to handle that reply if I can't always rely on it being JSON? In .NET we have a tryParse method available that would work great here, but as far as I know JQuery/Javascript has no such feature. If it can't parse the reply, it throws a JS error.
Here is where the custom JSON exception is thrown:
private HttpSessionState GetUserSession()
{
HttpSessionState session = HttpContext.Current.Session;
try
{
// This is a method we created that checks if user has timed out and throws the exception if so.
SessionBuilder.Create(session, HttpContext.Current.Request, HttpContext.Current.Response);
}
catch (SessionTimeOutException e)
{
throw new WebFaultException<SessionTimeOutException>(new SessionTimeOutException(e.Message), System.Net.HttpStatusCode.BadRequest);
}
return session;
}
And here is the client-side code that handles errors in my AJAX request:
error: function (HttpRequest)
{
// This is the line that gets the exception because the responseText is a standard .NET XML error, not my custom JSON error.
var parsedReply = $.parseJSON(HttpRequest.responseText);
if (parsedReply.ClassName === "SessionTimeOutException")
{
var url = "../timeout.asp?" + parsedReply.Message;
window.location.href = url;
}
}

JavaScript has try { ... } catch(ex) { ... } also.
error: function (HttpRequest)
{
var parsedReply;
try {
parseReply = $.parseJSON(HttpRequest.responseText);
if (parsedReply.ClassName === "SessionTimeOutException")
{
var url = "../timeout.asp?" + parsedReply.Message;
window.location.href = url;
}
} catch(ex) {
parsedReply = HttpRequest.responseText;
//Do something else
}
}

Related

failed to fetch using spring api on localhost

The javascript tries to fetch data from my spring boot api and gives back a "Failed to fetch" error everytime.
I'm sure the request reaches the api because for every click on submit I get the print statement, that i put in my get method, logged as it should. So something on the way back must be wrong.
Get method:
#RestController
#RequestMapping("/familyMember")
public class FamilyController {
private FamilyRepository familyRepository;
public FamilyController(FamilyRepository familyRepository) {
this.familyRepository = familyRepository;
}
#GetMapping("/id/{id}")
public FamilyMember getById(#PathVariable("id") Long id) {
Optional<FamilyMember> optional = familyRepository.findById(id);
if (!optional.isPresent()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
FamilyMember familyMember = optional.get();
System.out.println(id); //print statement to make sure api is reached
return familyMember;
}
Javascript code:
const url = 'http://localhost:4001/familyMember/';
submit.onclick = async() => {
const endpoint = url + 'id/' + input.value;
try {
const response = await fetch(endpoint); // error occures here because no code below is executed
output.style.color = 'green'; // to see if fetch continues(apparently it doesn't)
if (response.ok) {
output.innerHTML += await response.json();
}
} catch(error) {
output.innerHTML += error; // gives me "Failed to fetch" in the html
}
I'm not sure if the bug is on the server side or client side. The api gives me the correct information when I use curl in the terminal...so propably the js code?
Thanks in advance.
Actually found the answer. Above #RestController I need the annotation #CrossOrigin sothat the api allows requests from different origins than itself (in that case a html file).
#CrossOrigin
#RestController
#RequestMapping("/familyMember")
public class FamilyController {
...
You should specify cross origin with an adress like "localhost:4001"

Dojo Request from WMS 1.1.1 GetFeatureInfo

I am trying to get response from GetFeatureInfo of sample WMS. But getting
"Unable to load http://ogi.state.ok.us/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&SRS=EPSG:4326&BBOX=-104.5005,32.7501,-94.01,37.20&WIDTH=800&HEIGHT=300&LAYERS=ogi:okcounties&QUERY_LAYERS=ogi:okcounties&STYLES=&X=550&Y=105& status: 0"
var httpurl = "http://ogi.state.ok.us/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&SRS=EPSG:4326&BBOX=-104.5005,32.7501,-94.01,37.20&WIDTH=800&HEIGHT=300&LAYERS=ogi:okcounties&QUERY_LAYERS=ogi:okcounties&STYLES=&X=550&Y=105&";
try {
require(["dojo/request"], function (request) {
var promise = request(httpurl);
promise.response.then(
function (response) {
var kk = response;
},
function (error) {
var kk = error;
}
);
});
} catch (ex) {
alert(ex.message);
}
I see a couple potential issues:
Based on the request documentation, I think you should call .then() directly on your promise. Lke this:
promise.then(...);
on this line: var kk = data; ... you're using the variable data but you should be using response.
You may be getting a CORS issue - is your code running on the same domain as that URL? If not, and the website owner does not want to enable CORS for your domain, you may need to run a CORS proxy (google it)

cannot handle net::ERR_CONNECTION_REFUSED in pure js

I use pure js(without JQuery) to send an XMLHttpRequest request to server.
var _xhr = new XMLHttpRequest();
_xhr.open(type, url);
_xhr.setRequestHeader('Content-Type', 'application/json');
_xhr.responseType = 'json';
_xhr.onload = function () {
if (_xhr.status === 200) {
var _json = _xhr.response;
if (typeof _json == 'string')
_json = JSON.parse(_json);
success(_json);
} else {
error(_xhr);
}
};
_xhr.onerror = function(){
console.log('fail');
};
try {
_xhr.send(_to_send);
} catch (e){
options.error(_xhr);
}
when i send a request it's fails(this is ok) and i get an error but I CANNON HANDLE IT. xhr.onerror prints message to console but i get OPTIONS url net::ERR_CONNECTION_REFUSED too. How can I avoid this message in console?
Also i use window.onerror to handle all error but i can not handle this OPTIONS url net::ERR_CONNECTION_REFUSED
This worked for me:
// Watch for net::ERR_CONNECTION_REFUSED and other oddities.
_xhr.onreadystatechange = function() {
if (_xhr.readyState == 4 && _xhr.status == 0) {
console.log('OH NO!');
}
};
This is not limited to just net::ERR_CONNECTION_REFUSED because other network errors (e.g. net::ERR_NETWORK_CHANGED, net::ERR_ADDRESS_UNREACHABLE, net::ERR_TIMED_OUT) may be "caught" this way. I am unable to locate these error messages within the _xhr object anywhere, so making a programmatic decision about which network error has specifically occurred won't be reliable.
There is no way around that error showing in console. Just as if you request a file that does't exist you get a 404 in console, regardless of if you handle the error or not.

How to handle invalid URL / IP's in websockets?

I'm using HTML / Javascript web sockets to communicate with a python server program. Now I have the option to change the server's IP via clean UI and I have a .onerror function that handles with connection errors, however this doesn't handle initial errors. What I mean by this is if I were to enter a completely invalid address, it wont even attempt to connect with it (which is fine) and spit out and error like: [Error] WebSocket network error: The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.). How can I handle this error so I can say, popup a message for example?
Here's a brief overview of my JS script.
function updateDevice(id, ipUI){
if ("WebSocket" in window){
var ws = new WebSocket(serverIP);
// Here is where I need to handle the bad address right?
ws.onopen = function(){
ws.send(id);
};
ws.onmessage = function (evt){
var received_msg = evt.data;
};
// This function ws.onerror doesnt handle bad addresses.
ws.onerror = function(){
document.getElementById("error_msg").style.display='block';
};
}else{
alert("This site doesnt support your browser...");
};
};
You could wrap the new WebSocket in a try/catch:
try {
new WebSocket(serverIP);
} catch (e) {
if (e instanceof DOMException) {
alert('Invalid address!');
} else {
throw e;
}
}

Repeat failed XHR

Is there any common way, example or code template how to repeat a XHR that failed due to connection problems?
Preferably in jQuery but other ideas are welcome.
I need to send some application state data to a database server. This is initiated by the user clicking a button. If the XHR fails for some reason I need to make sure that the data is sent later (no interaction needed here) in the correct order (the user may press the button again).
Here's how I would do it:
function send(address, data) {
var retries = 5;
function makeReq() {
if(address == null)
throw "Error: File not defined."
var req = (window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
if(req == null)
throw "Error: XMLHttpRequest failed to initiate.";
req.onload = function() {
//Everything's peachy
console.log("Success!");
}
req.onerror = function() {
retries--;
if(retries > 0) {
console.log("Retrying...");
setTimeout(function(){makeReq()}, 1000);
} else {
//I tried and I tried, but it just wouldn't work!
console.log("No go Joe");
}
}
try {
req.open("POST", address, true);
req.send(data); //Send whatever here
} catch(e) {
throw "Error retrieving data file. Some browsers only accept cross-domain request with HTTP.";
}
}
makeReq();
}
send("somefile.php", "data");
To make sure everything is sent in the right order, you could tack on some ID variables to the send function. This would all happen server-side though.
And of course, there doesn't need to be a limit on retries.
jQuery provides an error callback in .ajax for this:
$.ajax({
url: 'your/url/here.php',
error: function(xhr, status, error) {
// The status returns a string, and error is the server error response.
// You want to check if there was a timeout:
if(status == 'timeout') {
$.ajax();
}
}
});
See the jQuery docs for more info.

Categories

Resources