How to properly ignore exception in Java? - java

We all write from time to time code like this:
try {
// ... some code.
} catch (SomeException e) {
// ... No action is required, just ignore.
}
Is there any standard code fragment like annotation to show we really intend to ignore exception? Something that shows to other team members and static analyzers we really need to skip this situation like InterruptedException after Thread.sleep()? Something like:
Exception.ignore(e);
Googled around but have not found something standard for such case.
This is especially relevant to tests that assure exceptions:
try {
action();
fail("We expected this to fail.");
} catch (ExpectedException e) {
ignore(e, "OK, so far so good.");
}

The only way to ignore an exception is to catch & swallow it, being very specific on the exception of course, you wouldn't want to catch Exception e, that would be a very bad idea.
try{
... //code
}
catch( VerySpecificException ignore){
Log(ignore);
}
Logging is obviously optional but a good practice.

in order to keep the code up with your exception handling or ignoring, it's nice to name the exception var as ignored:
try {
action();
} catch (ExpectedException ignored ) {}

Concerning your update referring to testing, if you use a testing framework, you can annotate the test in such a way that an exception is expected, e.g. using TestNG
#Test(expectedExceptions = ClassNotFoundException.class)
public void testSomething() {
// will succeed if a ClassNotFoundException is thrown
}

Related

Java-how to use annotation in Junit - eclipse

I am trying to test if a method throws a IllegalArgumentException in Junit with the code below, however it didn't work. Eclipse suggested to create an annotation class, which confuses me a bit. Can I get away without using an annotation? Otherwise what's the best solution for this?
#Test(expected = IllegalArgumentException.class)
public void testRegister(){
myProgram.register(-23); //the argument should be positive
}
I usually try catching the Exception I'm interrested in, and pass the test if it's caught. Try something like this:
try {
myProgram.register(-23);
// (optional) fail test here
}
catch (IllegalArgumentException e){
// pass test here
}
catch (Exception e) {
// (optional) fail test here
}
If you don't want to use an annotation you can catch all exceptions and test in an assertion that the exception is of instance IllegalArgumentException.
Exception e = null;
try {
// statement that should cause exception
} catch(Exception exc) {
e = exc;
}
// Assert that e is not null to make sure an exception was thrown
// Assert that e is of type IllegalARgumentException
But in the end it is much simpler to just use the JUnit annotation. Which seems to be correct to me.

Any problems with this exception handling approach?

We need to have two functions. They do the same thing but one handles the exceptions and one throws the exception. Note: If to handle exception, the exception has to be handled in the commonFunc() below. It would not work to handle the exception in functionHandlesEx() because to handle the function it needs the variable only available in commonFunc(). In order to re-use code, we got the following. Do you see any problem with it (I can see one problem is: the function throws exception but actually no exception is thrown when isExceptionHandled is true----but Java allows this)? Any better way to do this? We are in Java 6. Thanks.
public void functionThrowsEx() throws Exception e
{
commonFunc(false); //false means does not handle exception
}
public void functionHandlesEx()
{
try
{
commonFunc(true); //true means handle exception
}
catch (Exception e)
{
// do nothing as exception handled
}
}
private void commonFunc(final boolean isExceptionHandled) throws Exception
{
try
{
....
}
catch (Exception e)
{
if (isExceptionHandled)
{
//handle the exception
}
else
{
throw e;
}
}
}
This seems like an overly complicated approach to handling the exception. I understand its toy code to show what you are doing, but I haven't encountered many reasons to create nested calls in order to handle exceptions.
Ideally, the code that can cause the exception should have the means to handle the exception in it, using try...catch, and maybe finally. This logical flow looks like it would be pretty complex in a non-trivial application, and would lead to increased complexity and difficulty in debugging.
You should get rid of the two functions, and avoid nesting try/catch blocks. If you must nest them, make it has straigtfoward as possible by keeping the logic in the same method.
From the code, I'm guessing you want to handle the exception differently based on the state of the program. This code is too complex, and will be difficult to understand for a non trivial app. A better way would be to keep functionHandlesEx and put the exception recovery logic in the handler function.
public void functionHandlesEx() {
try {
//logic here;
}
}
catch (Exception e) {
if(iWantToHandleException) {
//handle exception
}
//do nothing otherwise. Use the finally block for anything else they have in common.
}
}
This is much simpler to understand, and it shouldn't be too hard to refactor it into this form.

Is it possible to monitor handled exceptions using JUnit?

This is what I have:
#Test
public testSendMessageToStub() {
// under the hood sends message
// if exception occurrs
// it will be catched and message will be put on retry
object.sendMessage();
}
Is there any way to mark test as failed if exception has occurred but was handled in catch block in the sendMessage() method?
Thanks
EDIT: It seems like I was too fixated on these legacy tests and how they were used, that totally missed the fact of sendMessage returning a response with a status code (!!!). So now I just assert status codes, can expand these tests into more detailed scenarios and spin them on jenkins. I would like to avoid to answer how these tests were checked previously. The thought to check for status codes came to me after reading Plux's answer. Thanks!
Exactly what you are looking for is not possible with JUnit as far as I know.
If you really would want to test this, you could store some information about the exception in the catch-block where it is handled in the sendMessage() method.
A better option, in my opinion, could be to test the output or state of the object. If the state/output is exactly the same as when an exception doesn't occur, then whats the point of testing it? Do you have an overly broad catch-block?
EDIT: To AdityaTS, I dont have enough reputation to comment on a post, but my comment: you have not supplied all the code, so I can not say for sure, but my guess is that its the Logger.getLogger IN the catch-block that casts the ClassNotFoundException. (Either that or loadConnectionInfo()) see http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html
You cannot do this without modifying sendMessage method. If for example you catch the exception there but choose to ignore it and just return some value, code outside of the method doesn't know it. You can get around this by refactoring the code of object: move the code that handles the exception to a separate method, called e.g. handleException. Then, in your test you can create a subclass where handleException will execute the original handleException from superclass, but additionally set some flag which you will be able to read in your test and in this way tell that the exception was thrown. However, if you cannot modify the code for object's class, I'm afraid you're out of luck.
So you expect the exception to propagate out of the sendMessage() method, right?
This is another way to write a test that verifies an exception you expect will be thrown.
#Test (expected = MyExpectedException.class)
public testSendMessageToStub() {
// under the hood sends message
// if exception occurrs
// it will be catched and message will be put on retry
object.sendMessage();
}
And it's usually best to be as specific as possible (e.g. MyExpectedException.class over Exception.class)
The exception generated in the sendMessage() class will be available in the test method. Add a try catch block around the sendMessage() method like this
#Test
public testSendMessageToStub() {
try
{
object.sendMehssage();
}
catch(Excpetion e) //Use more specific exception type if you know
{
fail(e.getMessage());
}
}
I have tried this in my code. It worked for me. Let me know.
public DBConnectionInfo connectionInit()
{
loadConnectionInfo();
try
{
Class.forName(dbObject.getDriver());
} catch (Exception e)
{
Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
lgr.log(Level.SEVERE, e.getMessage(), e);
}
try
{
dbObject.setConnection(DriverManager.getConnection(dbObject.getDatabaseURL(), dbObject.getUserName(),
dbObject.getPassword()));
} catch (Exception e)
{
Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
lgr.log(Level.SEVERE, e.getMessage(), e);
}
return dbObject;
}
The test case for the above class.
#Test
public void testDriverFailure()
{
when(dbModelObject.getDriver()).thenReturn("driver");
when(dbModelObject.getDatabaseURL()).thenReturn("jdbc:postgresql://127.0.0.1:5432/testdb");
when(dbModelObject.getUserName()).thenReturn("postgres");
when(dbModelObject.getPassword()).thenReturn("postgres");
try
{
dbConnector.connectionInit();
} catch (Exception e)
{
assertTrue(e instanceof ClassNotFoundException);
}
verify(dbModelObject).getDriver();
}

Try/Catch inside or outside functions

I have a very basic question about best practice of using try/catch.
I have a simple function (DAO) like this:
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
and using DAO function inside web service:
#WebMethod(operationName = "addVehicle")
public void addVehicle(Vehicle vehicle) {
try {
vehicleDAO.addVehicle(vehicle);
System.out.print("Vehicle added");
} catch (Exception e) {
e.printStackTrace();
}
}
OR is better using try/catch inside DAO function like this:
public void addVehicle(Vehicle vehicle) {
try {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
There is no perfect rule for that.
Often code is clearer and less complex if exceptions are catched as early as needed, but as late as possible.
You should think who has to take an action when that Exception happens, this decides if you catch it inside the method (addVehicle) or if you throw it such that the caller has to catch it.
E.g:
public void addVehicle(Vehicle vehicle) throws SQLException{
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
In this example the caller has to catch.
Further only in few situations you should catch Exception or RunTimeException, better
catch that specific Exception, like IOException instead of Exception.
Somewhere in your code you will need a "last line of defense" where it make sense to catch (Exception ex). This is needed to handle errors that should not happen.
When deciding where to handle a specific kind of exception, the best rule of thumb is to stop looking at the micro details of your code, take a step back to reason about your program's logic and consider these things:
Is the exception something that your program's current operation cannot recover from? If yes, it only makes sense to put the exception at the topmost level of that operation, to ensure that it doesn't continue.
If your program can work around that particular exception (perhaps by trying something else before giving up), take each layer of nested functions (starting from the highest) and each time ask yourself: If the exception occurs during the execution of some line of code in this function, would it make sense for this function to continue? As long as the answer is "yes", move to the deeper level. As soon the answer is "no", chances are this is the best place to put the handler for that exception.
Alternatively to the previous one, you could decide what would your program's alternate "plan of attack" be in case the exception is raised. Then, go to the line of code that would raise that exception and ask yourself: Does this function have enough context information to perform the workaround I have in mind? As long as the answer is "no", move to the caller function. As soon as the answer becomes "yes", consider putting your exception handler there.
That being said, you should only catch reasonably specialized exceptions and keep the catch(Exception ex) construct only as a last resort only at the top level and only after all the other possible catch blocks, reserving it only for kinds of exceptions you really couldn't predict at the time of writing. (I know you said this is not the point of the example, but since we're at it, I thought it should be mentioned to make this answer more complete.)
You should only catch those exceptions which you want to handle. You may include a topmost exception handler to turn any unhandled exceptions into something somewhat useful for the end user.
Instead of e.printStackTrace();, try return proper exception message.
find out more about exception handling here
Here is more discussion about exception handling.
AFAIK the best practice will be smth like that:
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
try {
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
if (em.getTransaction().isActive()) {
try {
em.getTransaction().rollback();
} catch (Exception e) {
// Log rollback failure or something
}
}
throw new RuntimeException(e);
}
}
Use both, the only reason is to use catch RuntimeException or even Throwable. Because this kind of exception is typically thrown by the underlying frameworks. An you should catch exactly this kind of exception if you want to make some actions, for example logging, print stack trace, etc., before you re-throw it again. If you don't do in such way you may loose the cause of exception.
#Transactional
public void addVehicle(Vehicle vehicle) {
try {
//do whatever with session
} catch (RuntimeException e) {
e.printStackTrace();
throw new Exception(e);
}
}

Handling Multiple Exceptions within a Method

I am currently working on the maintenance of a piece of code that is a little bit "Exception Happy." Basically, ever method or anything throws Exception. I'm going to work to take care of that, but, in the meantime, I am wondering what is the best way to handle individual exceptions within a smaller block of code, such as a method. Is it better to do something like this:
public void aMethod()
try {
//Lots of code in here. Many lines.
} catch(Exception e) {
// TODO - Handle All Exceptions, but fairly generically
}
}
Or something like this:
public void bMethod() {
try {
// One line of code.
} catch(Exception e) {
// TODO - Handle a specific Exception (may even involve rethrowing it with more information)
}
// More code.
try {
// Another line of code.
} catch(Exception e) {
// TODO - Handle another specific exception.
}
}
I realize this is a pretty basic question, but after looking at hundreds of methods with Exceptions coming out of every one, I'm starting to wonder how best to handle all of them and what a best practice may be here.
First off, you should only put code in try/catch blocks that is exception worthy. For instance, having an unexpected value is not necessarily an exception, but trying to read from a file that doesn't exist is.
To answer your main question, you should put the exceptionable code in the same try {} block and catch specific questions in order of granularity in multiple catch blocks after the main try.
//Regular code that doesn't need to be covered by a try/catch block
try {
//critical code only
} catch (NullPointerException npe) {
//Code
} catch (RandomException re) {
//code
} catch (Exception e) {
//code
}
The answer to your question is: it depends.
if the code in the try block is coherent where it makes no sense to proceed in the event of an error, the first approach is best
if the code is taking seperate steps that are relatively unrelated (parsing numbers for instance) and can be recovered without aborting the rest of the method the seconds appraoch makes sense
A general remark on the code you inherited; it sounds like exceptions are abused to pass state around, I would refactor so that exceptions are caught at the spot where they can be handled and introduce return values or attributes to handle the state.
your bMethod isn't very useful illustration. Try to reprase it. Anyway, you have two options:
catch exceptions and log them.
catch exceptions and throw new RuntimeException(ex) (rethrow a runtime exception, setting the original as a cause)
Also, you will need to differentiate between exceptions. If your system has many custom exceptions, they are probably defined for a reason, and specific behaviour is expected when one of them is thrown.
If the try/catch block isn't adding useful information, just allow the method to throw the exception and have it handled where the caller can sensibly do something with the exception. This could cut down the number of try/catch significantly (by an order of magnitude).
BTW a trick for rethrowing any exception is.
try {
// do something
} catch (Throwable t) {
Thread.currentThread().stop(t); // rethrow any exception.
}
In addition to the suggestions already made you may also want to consider extracting try/catch blocks from the "meat" of the function.
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
}
catch (Exception e) {
logError(e);
}
}
private void deletePageAndAllReferences(Page page) throws Exception {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
logger.log(e.getMessage());
}
This lets you focus your attention on the function you are really interested in without the exception handling getting in your way.

Categories