I'm following a Java programming course and we just learned Exception Handling in Java. I saw this code in the last homework correction:
public int getWinner() throws IllegalArgumentException {
int winner;
try {
winner = GameRules.getWinner(firstPlayer, secondPlayer);
} catch (IllegalArgumentException e) {
throw e;
}
return winner;
}
My question would be: Why do we first catch the Exception e and throw it again?
I think if you do so, then the program will still be stoped so it's like not handling the exception. Maybe I am wrong, please point it out, thanks!
Sometimes you catch an exception as you want to perform some logging/record some metrics as part of the process. Re-throwing the exception means you can then pass the exception higher up the call-stack so it can be dealt with by a (centralised) error handler.
Not all exceptions are unrecoverable just because they occur, so throwing an exception doesn't necessarily cause the application to stop unless its allowed to bubble all the way up the call stack.
Catching the exception simply gives you the opportunity to decide what to do next when the exception occurs. Catching an exception and then ignoring it is typically bad practice.
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();
}
I was reading about try-with-resource statement in Java which can be used to specify any number of resources.
try (Resource1 res1 = initialize_code; Resource1 res2 = initialize_code; ...)
{
statement;
}
Now when the try block exits (normally or abnormally throwing an exception) the close methods of all resource objects are invoked. But some close methods can throw exceptions. What will happen in that scenario if close itself throws exception?
But some close methods can throw exceptions.
Yes they can and you are right. Also the resources are closed in reverse order of their initialization.
What will happen if close method itself throws exception?
As you mentioned some close methods can also throw exceptions. If that happens when try block is executed normally then the exception is thrown to caller.
But what when another exception had been thrown, causing close
methods of the resources to be called, and one of the close method throws an exception (exception of lower importance actually)?
In this situation original exception gets rethrown and the exceptions caused by close method
are also caught and attached as supressed exception. This is actually one of the advantge using try-with-resource becuase implementing such mechanism would be tedious to implement by hand.
try {
///statements.
} catch (IOException e) {
Throwable[] supressedExceptions = ex.getSupressed();
}
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
}
writing a system in netbeans rcp - not sure if this matters, i just don't trust the rcp
We're approaching crunch time on our system and the following error keeps happening (sometimes it happens after 10 minutes, sometimes it runs for 2 days and then happens which is leading me to believe it could be a threading error)
we have a socket reader class which implements runnable - here is a sample of the code
#Override
public void run() {
while (!Thread.interrupted()) {
try {
/*
* can't display actual code
* reads data through socket and passes stream to a new handler class
* which uses reflection to create new object based off socket stream
* (none of this happens in a separate thread)
* (we're not holding a reference to the handler class - a new one is
* -created every iteration)
*
* at some point during the creation of this object, we get a socket
* closed exception happening at SocketInputStream.socketRead()
*/
} catch (Exception ex) {
cleanup();
}
}
}
what i expect to happen is that the socket exception should just be caught by the catch block and the cleanup executed
what ends up happening instead is i get a visible stack trace (pops up in the netbeans uncaught exception window and displays in the console) for java.net.SocketException socket closed - i cannot post the stack trace due to customer requirements
what else is strange is that in the actual socket input handler class we have the following method (this is the method that the exception is actually being thrown from)
public Abstract________ new________(Class<? extends Abstract________> clazz,
DataInput input) {
...
try {
// reflection code here
} catch (Exception ex) {
LOG.error("...");
throw new RuntimeException(ex);
}
...
}
if i try manually throwing the java.net.SocketException after the catch block the exception reads java.lang.RuntimeException: java.net.SocketException exception: socket closed
yet the stack trace that we receive randomly simply says java.net.SocketException: socket closed
this is leading me to believe that in our socket stream handling class it's not even catching the exception to begin with.
Does anybody have any input as to why this may be happening???
also - i am very sorry that i can't post the actual code, i'm not trying to be cryptic
so far the one thing i'm wondering about - i am somewhat familiar with reflection but not to a great extent - when i manually throw an exception it always gets caught by the try catch block - if an exception is thrown from something in reflection is there any way it could break the try catch contract - i don't see why it would but i mean, i'm honestly not sure and grasping for straws at this point
i have received permission to post an edited stack trace
in the MessageReader class there is no separate thread - the newMessage method is where the exception is being caught, wrapped into a RuntimeException and thrown up - the ____Reader is the socket reader with the while loop
both methods do show up in the stack trace
not sure if this will help
A thrown Error (java.lang.Error) may be bypassing your catch block (which is only catching Exceptions). Try catching Error and print out whatever debug statements you need. Don't forget to rethrow the error from the catch block.
It could also be that an Exception is being thrown in the catch block.
Two possibilities come to mind:
The exception is being caught higher up in the stack trace
or, the stack trace doesn't actually contain either of the methods you've pasted
In java, I want to log the exception being thrown from a piece of code:
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad");
throw t;
}
The problem is that now my method must declare it throws throwable.
On the other hand, if I log the exception in a finally block, how do I know what exception is being thrown (and if any exception is being thrown at all).
You could at least write a catch for unchecked and n catch blocks for checked exceptions.
try{
..
}catch(RuntimeException e){
log(e);
throw e;
}catch(ExceptionException ..){
log(e);
throw e;
}
This will not change the signature of your method. Catching Errors is a bit of a smell. Well, logging and throwing exception is a smell, too. This will duplicate error messages.
Advance exception handling is a feature that was removed from project coin in JDK 7.
This seems to be the wrong place to log the exception. Either log it within doRiskyThing() when throwing it, or log it where it is supposed to be captured.
This should work:
try
{
doRiskyThing();
}
catch(RuntimeException e)
{
log.warn("too bad");
throw e;
}
catch(Exception e)
{
log.warn("too bad");
throw new RuntimeException(e);
}
catch(Error e)
{
log.warn("too bad");
throw e;
}
But it's ugly and I'd rather have a single catch block that catches everything and logs it at the top level of the app, with no re-throwing. The stack trace lets you pinpoint the problem anyway.
Catching Throwable in itself is already bad practice (and flagged as such by many code quality checking tools). Wrapping it in a RuntimeException and rethrowing it? Terrible! The whole point of having an exception hierarchy is undermined by this.
The 'trend' away from checked exceptions is actually a bit more subtle. Between architectural layers (or for example at a framework API boundary) it is common practice to define one or more meaningful exception types and wrap any implementation-specific errors in them (take a look at Spring or Hibernate for example).
Making exceptions checked or not is a matter of style. If there is a good chance that the caller will be willing and able to handle the error condition then I make it checked (e.g. concurrent update detected), otherwise unchecked (e.g. database connection error). Unchecked exceptions should 'bubble' up through your application code (i.e. not be caught) and handled at a high level by displaying some sort of error page/screen.
You can log the Throwable, and throw a RuntimeException.
In Java, you have to declare any exception that your method might itself throw, because it's considered part of the method's signature.... that is, apart from RuntimeException, which avoids that rule. The RuntimeException can give the message of the Throwable as part of its message, if you like.
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad, exception thrown: " + t.getMessage());
throw new RuntimeException("Throwable exception was thrown, message: " + t.getMessage());
}
Beware however that this may be considered bad practice, and for more long-term code it's recommended that you throw a non-runtime exception and define it in the method's signature.