java: log exception being thrown - java

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.

Related

Exception handling in Java: catch and throw again

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.

What is a IOException, and how do I fix it?

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();
}

How to catch exception thrown by close method in try-with-resource statement

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();
}

is it possible to catch a fatal xml exception in java?

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.

Why would I care about IOExceptions when a file is closed?

I've see this sort of thing in Java code quite often...
try
{
fileStream.close();
}
catch (IOException ioe)
{
/* Ignore. We do not care. */
}
Is this reasonable, or cavalier?
When would I care that closing a file failed? What are the implications of ignoring this exception?
I would at the very least log the exception.
I've seen it happen occasionally, if the attempt to close the file fails due to it not being able to flush the data. If you just swallow the exception, then you've lost data without realizing it.
Ideally, you should probably swallow the exception if you're already in the context of another exception (i.e. you're in a finally block, but due to another exception rather than having completed the try block) but throw it if your operation is otherwise successful. Unfortunately that's somewhat ugly to sort out :(
But yes, you should at least log it.
You would care if the close() method flushes written content from a buffer to the filesystem, and that fails. e.g. if the file you're writing to is on a remote filesystem that has become unavailable.
Note that the above re. flushing applies to any output stream, not just files.
The most common close() problems are out-of-disk space or, as Brian mentioned, a remote stream that's gone poof.
NOTE:
You should really see something like (note: I haven't compile-checked this)
SomeKindOfStream stream = null;
Throwable pending = null;
try {
stream = ...;
// do stuff with stream
} catch (ThreadDeath t) {
// always re-throw thread death immediately
throw t;
} catch (Throwable t) {
// keep track of any exception - we don't want an exception on
// close() to hide the exceptions we care about!
pending = t;
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
if (pending == null)
pending = e;
}
}
if (pending != null) {
// possibly log - might log in a caller
throw new SomeWrapperException(pending);
// where SomeWrapperException is unchecked or declared thrown
}
}
Why all this?
Keep in mind that Java can only track one "pending" exception at a time. If the body of the main try block throws an exception, and the close() in the finally throws an exception, the only thing you'll know about is the close().
The above structure does the following:
Keep track of any throwable thrown in the body of the try
In case that exception is thread death, rethrow it immediately!
When closing, if we don't have a pending exception, track the close exception; otherwise the previously-thrown exception should be kept track of. (You should probably try to log the close() error in this case)
At the end, if there is a pending exception, deal with it. I usually wrap it and rethrow it. Personally, I use an unchecked wrapper so I don't need to have all callers in the call chain declare throws.
To do the above, I usually use the template method pattern to create the exception management and then override a doWork() method that is the body of the try.

Categories

Resources