I have a very basic question about best practice of using try
/catch
.
I have a simple function (DAO) like this
public void addVehicl
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);
}
}
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);
}
}
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:
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.)
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.