I'm trying to make a json object from the result of the googleplaces api. But one line of code is causing me alot of problems. My question is how the heck do i find what the issue is. I can't seem to catch the right exception (im a noob at debugging though). The url that i am passing in has the value:
https://maps.googleapis.com/maps/api/place/search/json?location=34.7,-86.5&radius=16000&types=food&name=mcdonalds&sensor=true&key=(myApiCodeWhichImNOTPostingHere)
^i do have the correct apicode and the link works ourside of android.
here is the method in question (highlighted is the line that is causing problems).
public static JSONObject getTheJSON(String url){
JSONObject json=null;
try{
DefaultHttpClient myHttpClient = new DefaultHttpClient();
HttpPost myHttpPost = new HttpPost(url);
//this line below is giving me problems (jumps streight to the catch Exception)
HttpResponse response = myHttpClient.execute(myHttpPost);
//this line above is giving me problems(jumps streight to the catch Exception)
String data = EntityUtils.toString(response.getEntity());
json= new JSONObject(data);
//parse the JSONObject
} catch (UnsupportedEncodingException e){e.printStackTrace();}
catch (ClientProtocolException e){e.printStackTrace();}
catch (IOException e){e.printStackTrace();}
catch (JSONException e) {e.printStackTrace();}
catch (NullPointerException e){ Log.e("My APP", "exception: " + e.getMessage());}
/* jumps to line below (skips the other catch exceptions)
the log reads "null" since i use the "getMessage()" so thats not useful*/
catch (Exception e ) { Log.e("My APP", "exception: " + e.getMessage());}
return json; // returning the JSON object
}
(Edit):
Here is the logcat. i think im getting a connection to factory client error
10-16 21:11:30.105: E/My APP(980): exception
10-16 21:11:30.345: E/MapActivity(980): Couldn't get connection factory client
Instead of using e.getMessage(), use e.printStackTrace() (outside of the Log.e() method, but within the catch clause) so you can trace what the real problem is. If you do not get any wiser from that, please post the stacktrace here.
Edit (see commments):
My LogCat (without filters) always displays the stacktraces in a correct way, but after a bit of searching it seems that that is not always the case:
See this SO question.
You should use three(!) arguments with the Log.e method.
Example:
Log.e("My APP", "exception", e);
You might want to check your SSL setup. You are calling a https:// url
I ran your code in eclipse and it ran fine giving me a valid response. I think this is probably SSL related. You could enable SSL debugging by doing -Djavax.net.debug=all
Can you paste the output log after enabling SSL debugging?
Related
I have a service that looks like this:
public String storeTestRequest(Map<String, String> data, HttpSession session) {
JSONObject json = new JSONObject(data);
boolean hasHealthInsurance = json.getAsString("hasHealthInsurance").equals("true");
try {
this.testRequestRepository.save(new TestRequest(
json.getAsString("firstname"),
json.getAsString("surname"),
json.getAsString("street"),
hasHealthInsurance
));
return "All good.";
}
catch (Exception e) {
return "Something went wrong.";
}
}
In this example, I am saving the values of 4 fields but in fact there are much more and I don't want to validate any of them. So if all values could be saved successfully, I should get the message All good. But if some values are missing, I should get the message Something went wrong..
I have tried it with try & catch but I still get a 500 error.
Your hasHealthInsurance property is empty or null. Your exception message says it's caused by this line.
boolean hasHealthInsurance = json.getAsString("hasHealthInsurance").equals("true");
If you put this line in your try catch block, you will see the exception message in the catch block.
I am currently working on a service that hit another service from another team, which gives the response code 500 when the service has no data to be sent. At first, I can utilize the HttpServerErrorException.InternalServerError to catch the exception and get the response body. However, this did not work as it used to. That error was not caught by that Exception and when I tried using catch (Exception e), it also caught nothing and let it through that makes the service not running correctly..
Below is the code, what is actually wrong from my code below? How should I handle that 500 response code?
Map resultMap1;
try {
resultMap1 = restTemplate.postForEntity(url, request, Map.class);
} catch (HttpServerErrorException.InternalServerError e) {
resultMap1 = new HashMap();
resultMap1.put("errorMessage", e.getMessage());
return resultMap1;
} catch (HttpServerErrorException.GatewayTimeout e) {
throw new AppException(
GATEWAY_TIMEOUT_CD,
GATEWAY_TIMEOUT_MSG +": "+ url,
null
);
} catch (HttpServerErrorException.BadGateway e) {
throw new AppException(
BAD_GATEWAY_CD,
BAD_GATEWAY_MSG +": "+ url,
null
);
} catch (HttpServerErrorException.ServiceUnavailable e) {
throw new AppException(
SERVICE_UNAVAILABLE_CD,
"The service "+ url +" was unavailable.",
null
);
}
Map returnMap = new HashMap(); // this is to be the result from my service
switch (resultMap.get("content_type")){ // In this one, I get NullPointerException
// Here would be selection how the content should be treated, different content have different treatment
}
I know that the NullPointerException can actually be handled by adding ELSE or another case, However, I curious about why the Exception wasn't caught well as it supposed to be.
I'm trying to make a simple http request in my android app.
((HttpURLConnection) new URL("https://omg-a-site.org").openConnection()).getResponseCode();
I tried using java.net.URL.getInputStream and java.net.URLConnection.getInputStream, but it just wont work. Am I doing something wrong?
Your code is doing something.
Here is a try-catch with your code inside the "try" block. If any IOExceptions occur, the catch block will print out whatever is in the exception text.
try {
((HttpURLConnection) new URL("https://omg-a-site.org").openConnection()).getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
That code will produce the output below,
which looks reasonable – it cannot find a host named "omg-a-site.org":
java.net.UnknownHostException: omg-a-site.org
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:299)
at java.base/sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:174)
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:498)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:603)
at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:266)
at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:380)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:189)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1242)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:175)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1665)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:529)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:308)
at a68.main(a68.java:8)
The problem I'm trying to solve is like this: I'm trying to scrape some content from a web page, I'm using selenium, findElementByClassName to get the element content, and it works great until now. But considering that the website that I'm scraping changes one of those element classes in html, I don't want to get an could not find element exception making the rest of the code not execute and jumping straight into the catch block.
My idea was to put each line of code into a try catch block, but having about 15 fields that I want to scrape it makes the code look ugly. See for yourself:
String name = null;
String type = null;
String description = null;
try {
driver.get(link);
try {
name = driver.findElementByClassName(environment.getProperty("booking.propertyName")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
type = driver.findElementByClassName(environment.getProperty("booking.propertyType")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
description = driver.findElementByClassName(environment.getProperty("booking.propertyDescription")).getText();
}catch (Exception e){
log.error("error doing thing");
}
}catch (Exception e){
log.error("Error during scraping");
}
So if one of these things goes wrong, I still want the rest of the code to continue instead of when having one try-catch block where the first thing failing would stop the other things from executing.
The code above works just fine but it does not look good so my question do you have any ideas of how I could make this better looking.
There is no magic bullet for this. But the standard way avoid repetitive code is to refactor. For example:
try {
type = driver.findElementByClassName(environment.getProperty("something"))
.getText();
} catch (Exception e){
log.error("error doing thing");
}
can be rewritten as:
type = getElementTextIgnoringExceptions(driver, environment, "something");
where getElementTextIgnoringExceptions has been defined as something like this:
public String getElementTextIgnoringExceptions(
Driver driver, Environment env, String name) {
try {
String className = env.getProperty(name);
return driver.findElementByClassName(className).getText();
} catch (Exception ex) {
log.error("error getting " + name, ex);
return null;
}
}
However ... there are some bad things about the code that you are trying to simplify here:
Catching Exception is bad. You have no idea what you will catch, or whether it is safe or sensible to continue.
Not logging the exception is bad. How are you going to diagnose the problem if all you have an "error doing thing" message in your log file?
Continuing after the exceptions is (in the context of your application) liable to cause problems. The rest of your code will be littered with null checks to deal with the elements (or whatever) that couldn't be fetched. Miss one check and you are liable to get an NPE; e.g. in some edge-case that you didn't cover in your unit tests.
These issues are more significant than making the code look good.
If you are using Java 8+, it may be possible to refactor so that the logic is passed as lambda expressions. It depends on the nature of the variables used.
I am connecting to a website using Jsoup. I have inserted a .timeout to check if the website times out.
Because I already handle IOException, my IDE is not allowing me to put another catch for SocketTimeOutException, which is fair, I guess.
Is there a way to tell from IOException what is the error?
I'd like to have specific debugging output for different errors, so that I can keep the code clean and efficient.
Here is my code (yes, some variables are missing, they are pretty simple though and not really necessary):
Document doc = null;
try
{
doc = Jsoup.connect(Url).proxy(proxy).userAgent(userAgent).timeout(10000).get();
}
catch (IOException e)
{
if (...)
{
if(specificThread.running == false) {
System.out.println("Thread got interrupted! Link visited -> "+ Url);
Thread.currentThread().interrupt();
}
try
{
System.out.println("Localhost detected! If this happens, you're stupid");
doc = Jsoup.connect(Url).userAgent(userAgent).get();
}
catch (IOException e1)
{
System.out.println("Couldn't connect to " + Url + " , localhost was detected.");
e1.printStackTrace();
System.exit(-1);
}
catch (java.lang.IllegalArgumentException error)
{
System.out.println("Malformed URL detected -> " + Url) ;
}
}
else
{
System.out.println("Couldn't connect to " + Url);
e.printStackTrace();
}
}
catch (java.lang.IllegalArgumentException error)
{
System.out.println("Malformed URL detected -> " + Url);
}
catch (java.net.SocketTimeoutException error) //IDE Is blocking this
{
//Handle error here
}
Is it possible to do this?
Put the catch for the SocketTimeoutException before the catch for the IOException.
Exception handling works by looking through a table until a matching exception type is found. As such, more specific exceptions have to come before more general exceptions, in order that they can be matched.
This is described in JLS Sec 14.21, "Unreachable Statements":
It is a compile-time error if a statement cannot be executed because it is unreachable.
...
A catch block C is reachable iff both of the following are true:
...
There is no earlier catch block A in the try statement such that the type of C's parameter is the same as or a subclass of the type of A's parameter.
So, you just need to make sure there is no earlier catch block catching a superclass parameter.