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)
Related
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.
The following java code runs in an IntentService; it works; it uploads an image to twitter.
I have coded it with a separate try-catch at each call that throws an IOException.
I have removed code at the ... spots to make it quicker to read.
try {
con = (HttpURLConnection) new URL(Constants.TWITTER_ENDPOINT_UPLOAD_MEDIA).openConnection();
} catch (IOException e) {
e.printStackTrace();
}
...
con.setDoOutput(true);
try {
os = con.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream out = new DataOutputStream(os);
try {
write(out, boundary + "\r\n");
...
} catch (IOException e) {
e.printStackTrace();
}
try {
statusCode = con.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
My question is:
Does it make sense to put one or more of these calls inside a re-try loop, like this:
for (int i = 0; ; i++) {
try {
httpURLConnection = (HttpURLConnection) new URL(Constants.TWITTER_ENDPOINT_UPLOAD_MEDIA).openConnection();
break;
}
catch (IOException e) {
if (i < 3) {
continue;
}
else {
reportErrorToCallingActivity();
return;
}
}
}
And, if it does make sense, at which ones?
And, if for example I were to need to re-try at:
statusCode = con.getResponseCode();
how much code should I re-run: all the way back to openConnection?
I just can't figure this out from the documentation,
and I don't want to just guess at what to do. Hope you can help!
I appreciate this is probably greatly cut-down, but I think the giveaway here is that when you catch your IOExceptions all you do is log them to the console. In other words, your code doesn't know what to do, what state it (or the connection) is in, or how to proceed. Given that checking exception message text is bad practice, the exception type just doesn't give good enough information. In that case, the simplest and most honest thing is to rethrow the original exception in the hope that the calling code knows more / can handle the error better.
If, at any stage, you (or your code) are confident you can fully/largely deal with an exception, then have an explicit try/catch the way your current code does. But if you don't, your method should 'fess up' and declare that it throws IOException without trying to handle them at all. (Make sure you have a finally block to clean up any resources you've created in the process!)
Provided your method is honest and cleans up after itself, the calling method can potentially retry in a loop - as per your second code example. However, without any controls on retrying (number of attempts, backoff, etc.) and without any good guidance from the connection API, it's probably unwise to keep trying, potentially wasting resources, getting rate-limited, breaching T&Cs etc.
A better solution would be to obtain a Twitter access library that returns meaningful status messages, and that can potentially handle its own retries.
Edit:
By far the most useful line is statusCode = con.getResponseCode(); which gives you a value you can check against Twitter's Error Codes list. In general, if you get 2xx back, your request has succeeded, 4xx means your code has done something wrong, 5xx means Twitter has done something wrong. At least that lets you adjust your error message if you - as you probably should - bail out rather than try to work around it.
It looks like 420 and 429 best indicate that you can retry. However, you will need to do so much more carefully than just repeating your request in an endless loop. You should definitely read the Rate Limits doc for guidance.
I have a need to save a xml file in a directory .....if it is not well formed.
Just to analyze it for the reason for the failure.
How do i save the xml request in a directory in catch block?
i tried doing it..but the variables created in the try block seems undefined in catch block. I am a newbie...sorry if its a basic question. any solutions?
try {
Create a well formed xml request
open a http connection and post it
}
//catching all exceptions here
catch (Exception e) {
e.printStackTrace();
}
The {} braces are scoping the variables that are inside your try block, so they're not available outside of that scope. You could do something like this:
String xml = null;
try {
xml = ...; //Create a well formed xml request
//open a http connection and post it
} catch (Exception e) {
if (xml != null) {
// write XML to file
}
}
If you define your variable outside/before the try block, you can use it inside the catch. Really though, you should consider why you are using try/catch error handling as flow control.
You have to declare the variable outside of the try block, then it would work
XmlDocument xml = null;
try {
xml = Create a well formed xml request
open a http connection and post it
}
catch (Exception e) {
xml.save();
}
As you said, any variable declared inside the try block is not available in the catch block, so you have to place it outside
if you create a new element in an inner block it is unreachable out of it.
So if you create something in try block it is just visible on it. You cannot reach that out of the block.
So for your problem you should create xml request out of try block.
Something like this;
Create a well formed xml request
try {
open a http connection and post it
}
//catching all exceptions here
catch (Exception e) {
e.printStackTrace();
}
I'm using java to connect to http server. All is fine. Of course I catch exceptions (SocketTimeoutException, ConnectException, IOException). But my problem is when (for example) an ConnectException occurs, the app stay stucked. I can't anymore continue in an other part of program... I tried "return ..", System.exit (but I don't want to exit from application). Any idea ?
The skeleton prog looks like this:
boolean metod_to_check_http_server(){
try{
Create_connection(URL);
Set_Time_Out(3000);
open_HTTP_Connection();
Close_Connection();
return true; // All this part is fine...
}
catch (EXCEPTIONS)
{ // Here I know I have connection problem
// how could I return to main prog from here ?
// return false ? not work...
// System.exit(..); // too violent !
// so ?
}
If you add finally block to your try - catch statement you can continue your flow
try
{
}
catch{
}
finally{
}
Try to put finally block in you code after the catch one.
Your question cannot be answered without knowing more about your program and environment, but it might be a good idea to inform the user about the connection failure, for example in a dialog saying "Connection failed". And don't forget to close any open connections in a finally block.
You should do exception handling yourself, and return a false if connection fails or is invalid....
boolean method_to_check_http_server(){
try{
Create_connection(URL);
Set_Time_Out(3000);
open_HTTP_Connection();
return true; // All this part is fine...
} catch (EXCEPTIONS) {
displayError();
return false;
} finally {
Close_Connection();
}
}
As you can see, I made sure that my connection is closed (in the finally block) so that I don't leave opened sockets running in some OS thread somewhere.
This questions is related to java exceptions, why are there some cases that when an exception is thrown the program exits even though the exception was caught and there was no exit() statement?
my code looks something like this
void bindProxySocket(DefaultHttpClientConnection proxyConnection, String hostName, HttpParams params)
{
if (!proxyConnection.isOpen())
{
Socket socket = null;
try {
socket = new Socket(hostName, 80);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try
{
proxyConnection.bind(socket, params);
}
catch(IOException e)
{
System.err.println ("couldn't bind socket");
e.printStackTrace();
}
}
}
and then
I call this method like this:
bindProxySocket(proxyConn, hostName, params1);
but, the program exits, although I want to handle the exception by doing something else, can it be because I didn't enclose the method call within a try catch clause? what happens if I catch the exception again even though it's already in the method? and what should I do if i want to clean resources in the finally clause only if an exception occurs and otherwise I want to continue with the program? I am guessing in this case I have to include the whole piece of code until I can clean the resources with in a try statement or can I do it in the handle exception statement?
some of these questions are on this specific case, but I would like to get a thorough answer to all my questions for future reference. thanks
edit:
java.net.UnknownHostException: www.dsewew324f.com
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at homework3.Proxy.bindProxySocket(Proxy.java:666)
at homework3.Proxy$3.handle(Proxy.java:220)
at org.apache.http.protocol.HttpService.doService(HttpService.java:293)
at org.apache.http.protocol.HttpService.handleRequest(HttpService.java:212)
at homework3.Proxy.start(Proxy.java:472)
at homework3.Proxy.main(Proxy.java:1282)
Exception in thread "main" java.lang.IllegalArgumentException: Socket may not be null
at org.apache.http.impl.DefaultHttpClientConnection.bind(DefaultHttpClientConnection.java:80)
at homework3.Proxy.bindProxySocket(Proxy.java:674)
If
socket = new Socket(hostName, 80);
throws an exception then socket will be null and
proxyConnection.bind(socket, params);
will throw a NullPointerException, which you do not catch.
Are you sure the exception was caught? Your catch block only catches certain exceptions. A Runtime exception could be getting thrown which would not be caught..
Could it be that your program is simply coming to it's natural conclusion (exits from the main method)?
If your program is exiting because of an exception thrown from the main method then it should be printed to the console. Can you provide this stack trace?
May be that proxyConn is null, and because
if (!proxyConnection.isOpen())
it is not in a try/catch block it may generate an unhandled exception that causes your program to exit.
To answer some of your questions: what happens if I catch the exception again even though it's already in the method?
To put it simply, you can't. Once an exception is caught once, it is no longer on the top of the stack so any further attempts to catch it will fail
what should I do if i want to clean resources only if an exception occurs and otherwise I want to continue with the program?
If you want to do some action, any action, only when an exception occurs you should do this in your catch block.
I am guessing in this case I have to include the whole piece of code until I can clean the resources with in a try statement or can I do it in the handle exception statement?
I already answered this question with the one above :P
Like I said in my comment on marcus' post you should put a try catch around the call to the function itself to ensure that any other exceptions are being caught. You can figure out what to do from there when you know what exceptions aren't being caught.
try{
bindProxySocket(proxyConn, hostName, params1);
}
catch(Exception e){
e.printStackTrace():
}
You shouldn't continue the code after an exception which may cause that the code cannot continue.
Rewrite your code as follows:
Socket socket = null;
try {
socket = new Socket(hostName, 80);
try
{
proxyConnection.bind(socket, params);
}
catch(IOException e)
{
System.err.println ("couldn't bind socket");
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Better practice is just to let that exception go and declare a throws in your method. You should only handle the exception where it makes sense to handle it. Don't suppress the exceptions by just printing the trace and then continuing with the program flow.