I've got a program that uses JSoup to connect to and parse data from a website. When the website fails to connect after the 10 second timeout I've given it, the JSoup method throws an UncheckedIOException. This may contain an IOException like "SSL Peer shut down unexpectedly" or "timed out" which are IOExceptions I've dealt with in the past. It's weird because it wrapped in a try catch:
Document document;
try {
document = Jsoup.connect("https://www.website.com").timeout(10000).maxBodySize(0).get();
} catch (Exception e) {
return false;
}
Elements elements = document.select("tr");
for (Element e : elements) {
System.out.println(e.text());
}
return true;
I've done all sorts of workarounds like wrapping the method in a try catch, making the method throw exception and handling it higher up, and the above where I've isolated the line causing the issue and wrapped only that in a try catch. I've tried catching Exception, IOException, UncheckedIOException, etc but it all eventually still causes the whole application to crash due to the error seeping through somehow.
I've never encountered something like this. How is it that a try catch can't deal with the error? Is it the way JSoup has set up their error system? This can't be right, can it? I'm using JSoup 1.11.2 if that helps, downloaded from https://jsoup.org/download.
The issue was that an Error was not being caught because I was trying to catch an Exception. JSoup throws an Object that extends Error, not Exception, so when I did
try {
} catch (Exception e) {}
I should have done
try {
} catch (Error e) {}
Related
What are IO Exceptions (java.io.IOException) and what causes them?
What methods/tools can be used to determine the cause so that you stop the exception from causing premature termination? What does this mean, and what can I do to fix this exception?
Java IOExceptions are Input/Output exceptions (I/O), and they occur whenever an input or output operation is failed or interpreted. For example, if you are trying to read in a file that does not exist, Java would throw an I/O exception.
When writing code that might throw an I/O exception, try writing the code in a try-catch block. You can read more about them here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Your catch block should look something like this:
try {
//do something
}catch(FileNotFoundException ex){
System.err.print("ERROR: File containing _______ information not found:\n");
ex.printStackTrace();
System.exit(1);
}
Here you go https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
IOException is thrown when an error occurred during an input-output operation. That can be reading/writing to a file, a stream (of any type), a network connection, connection with a queue, a database etc, pretty much anything that has to do with data transfer from your software to an external medium.
In order to fix it, you would want to see the stack trace of your exception or at least the message, to see exactly where the exception is thrown and why.
try {
methodThrowingIOException();
} catch (IOException e) {
System.out.println(e.getMessage()); //if you're using a logger, you can use that instead to print.
//e.printStackTrace(); //or print the full stack.
}
The error message that will be printed will likely show you what the issue is. If you add the error message here, I'll be able to give you more info on how to fix that specific IOException. Without that, no one can really give you a complete answer.
It is a very generic exception that a lot IO operation can cause. A best way is to read the Stack Trace. To continue the execution you can use the try-catch block to bypass the exception, but as you mention you should investigate into the cause.
To print the stack trace:
try {
// IO operation that could cause an exception
} catch (Exception ex) {
ex.printStackTrace();
}
IOException is usually a case in which the user inputs improper data into the program. This could be data types that the program can't handle or the name of a file that doesn't exist. When this happens, an exception (IOException) occurs telling the compiler that invalid input or invalid output has occurred.
Like others have said, you can use a try-catch statement to stop a premature termination.
try {
// Body of code
} catch (IOException e) {
e.printStackTrace();
}
When handling errors in Java it's common to see the superclasses being the errors that are caugh, such as
Exception, IOException, SocketException, etc.
However how do you go about finding the nitty-gritty details on the exception? How do you single a certain exception type out from the others. For instance, I'm currently working on a small project using Netty.io which throws an IOException for every type of read/write error you can name. This makes sense, because ultimately this is input/output errors, but how would I handle them individually.
Example exceptions:
java.io.IOException: An existing connection was forcibly closed by the remote host
java.io.IOException: Connection reset by peer
java.io.IOException: Stream closed
The list just continues to go on, but how would you go about handling these seperately, one approach that I've found while looking around and seems really nasty is the following.
try {
// ...
} catch (IOException e) {
if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) {
// Handle error
} else //...
}
This seems very tedious and there's bound to be a better way to do this, a correct way if you will. I've looked through quite a bit of error handling writeups over the last few hours and they all only talk about the big boys that are used commonly. IOException, Exception, SocketException, NullPointerException, and FileNotFoundException. Where I believe SocketException and FileNotFoundException would be directly related to the IOException, more than likely a subclass, correct me if I'm wrong.
Anyway, what's the proper way to go about handling these exceptions and how do you figure out exactly what kind of exception you need to be handling? All I can really do is handle IOException until something more precise comes up, but when developing applications it's always good to be able to handle each error uniquely.
In most of these cases the message is irrelevant from the point of view of your code. It's just something to be shown to the user, or logged. The only salient fact is that the connection is broken, for whatever reason, and there aren't different code paths you can use depending on which message it was.
The only one that's different is 'socket closed', which indicates a coding bug.
EDIT Regarding your comments below:
Any IOException other than SocketTimeoutException on a socket is fatal to the connection.
Invalid packets don't cause IOException: that's an application-layer problem that throws application-layer exceptions, or subclasses of IOException: e.g., java.io.StreamCorruptedException.
There is no such thing as IOException: connection closed by remote host. If the peer closes the connection, that causes an end-of-stream condition, which manifests itself as either read() returning -1, readLine() returning null, or readXXX() throwing EOFException for any other X.
I would suggest catching the exceptions in order, from most specific to least - such that you will notice a circuit break pattern when the exception you are looking for is reached. This is the best I can come up with:
try {
/// Something that can result in IOException or a SocketException
catch (IOException e){
//Do something specific
}catch (SocketExcpetion e){
}catch (Exception e) { //or some superclass of the above exceptions
///
}
Don't forget that you can also catch multiple exceptions of different types using the | command: catch (IOException|SocketException|
The documentation (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) contains a long list of direct subclasses. You might want to look through them and check which ones you want to treat differently.
Once you know that, you can use multiple catch-blocks, first the subclasses, then the most general IOException:
catch(SSLException se) {
// do something
}
catch(HttpRetryException he) {
// do something else
}
catch(IOException ioe) {
// nop
}
When i do DOM XML Schema validation i get this error when there is a syntax error in my deliberately-incorrect test file.
[Fatal Error] :10:3: The element type "gizmos" must be terminated by the matching end-tag "</gizmos>".
However, I want to catch this so that it wouldn't give the red fatal error warning, instead a message that says something like "your xml is not valid." Is it possible?
Thanks,
I believe you can catch Throwable to handle your scenario
try{
....
....
....
}catch (Exception e) {
e.printStackTrace();
}catch (Throwable t) {
t.printStackTrace();
}
Errors can not be catched, only Exceptions can be catched.
According to Java Docs :
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.
But still, you can catch Throwable to catch any error. That is not recommended though.
catch (Throwable e) {
//e.printStackTrace();
}
You can catch a Throwable (Error extends Throwable):
try {
//...
} catch(Throwable e) {
//...
}
Please note that it's often recommended not to do it. You can read more about it here: When to catch java.lang.Error?.
If you are using the JAXP validation API then you can nominate an ErrorHandler to receive notification of errors. With this you can change what messages are displayed and where they are displayed.
I'm working on a project where an android application is communicating with a PHP server (WAMP) where some methods are implemented. We're using XMLRPC to handle client calls to server's methods. Anyway, even though everything happens fine, an exception is thrown when java tries to read the answer. So I would like to know if there is any way to read or save the server's response before java throws the exception (which is not really relevant) ?
Thanks in advance for your help !
The usual approach is to catch and handle this unchecked exception in your code. If you don't catch it, it will cause the application to stop.
Wrap the piece of code that causes the exception into a try/catch statement. This should allow you application to continue and you should be able to keep and process the response.
I do already set up a try/catch statement as you can see :
Integer result2 = null;
try {
Object[] dataParams = new Object[]{bytes, date, login};
result2 = ((Integer) client.execute("storeData", dataParams)).intValue();
System.out.println(result2.toString());
} catch (Exception ex)
{
ex.printStackTrace();
}
The storeData method is supposed to return an int. But as I get an exception, I can't see that response.
This is the error I get : [Fatal Error] :1:1: Content is not allowed in prolog.
I assume it's due to some bad characters in the xml response so that's why I'd like to get this response !
I have a thread in a Java web application that causes a java.lang.OutOfMemoryError: Java heap space exception, but the try/catch block does not catch the error.
Sample code:
private void doSomeWork()
{
try
{
processData(); //Causes OutOfMemoryError
System.out.println("This line does not execute");
}
catch (Exception e)
{
System.out.println("Exception. This line does not execute.");
//Log error
}
finally
{
System.out.println("finally. This line does execute");
System.out.println("Thread name: " + Thread.currentThread().getName());
}
}
Output:
finally. This line does execute
Thread name: _Worker-8
Exception in thread "_Worker-8" java.lang.OutOfMemoryError: Java heap space
...
Background:
I recently took over this Java project and I'm trying to get up to speed with Java and this project. I'm a C# developer, so I'm not yet familiar with this project or Java.
I know I can fix the error using the -Xmx setting, but I'm interested in catching this error so I can log it. The error is not showing up in any of the logs files, and the output is being shown in the console in debug mode in Eclipse.
Because OutOfMemoryError is an Error, not an Exception. Since OutOfMemoryError isn't a subclass of Exception, the catch (Exception e) doesn't apply.
OutOfMemoryError does extend Throwable, however, so you should be able to catch it. Here's a SO discussion on when (if ever) you should catch Errors. Generally, since you can't do anything about it, the recommendation is to not bother catching Errors in production code. But given a special case where you're trying to debug what's going on, it might be helpful.
java.lang.OutOfMemoryError doesn't extends java.lang.Exception so it's not an Exception. OutOfMemoryError extends java.lang.Error. If you want to catch Error try this:
private void doSomeWork()
{
try
{
processData(); //Causes OutOfMemoryError
System.out.println("This line does not execute");
}
catch (Error e)
{
System.out.println("Exception. This line does not execute.");
//Log error
}
finally
{
System.out.println("finally. This line does execute");
System.out.println("Thread name: " + Thread.currentThread().getName());
}
}
Note: Exception and Error extends Throwable so you you can also use Throwable to catch both.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html
An "~Error" is not an "~Exception".
You have to catch "Error" or "Throwable"
OutOfMemoryError extends VirtualMachineError while Exception extends Throwable directly. So it is not being caught as per Java specs. IF you're looking to catch all exceptions, add catch (Throwable e) to the clause and you'll have it.
What I will usually do is add an 'UncaughtExceptionHandler' to a Thread so if anything leaks by you at least have a chance to log the issue and maybe do some cleanup.