Verbose exception catch clauses - java

Background
I have a case where my logic requires surround with try/catch, I have a lots of catch clauses, which makes my code a bit ugly. What I do in catch clause is only log the error using log4j.
Question
Is it ok to use one catch clause with parent exception type instead of bunch of catch clauses?
Instead of this:
try{
//some statements
} catch (KeyStoreException e) {
LOGGER.error(e);
} catch (CertificateException e) {
LOGGER.error(e);
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e);
} catch (FileNotFoundException e) {
LOGGER.error(e);
} catch (IOException e) {
LOGGER.error(e);
} catch (UnrecoverableKeyException e) {
LOGGER.error(e);
} catch (NoPropertyFoundException e) {
LOGGER.error(e);
}
using :
try{
//some statements
} catch (Exception e) {
LOGGER.error(e);
}
Which one is better?

When catch exceptions I usually find that more specific is better, that being said typing out all of those different blocks that do the same thing can get really annoying. Thankfully in the Java 7 release a try-catch notation was added where you can specific multiple exceptions for a single block:
try{
//some statements
} catch (KeyStoreException |
CertificateException |
NoSuchAlgorithmException |
FileNotFoundException |
IOException |
UnrecoverableKeyException |
NoPropertyFoundException e) {
LOGGER.error(e);
}
This sounds like what you are looking for, but there is more detailed information in the Oracle docs: http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html

Is it ok to use one catch clause with parent exception type instead of bunch of catch clauses?
Hunter has provided the correct solution for Java 7 and later.
For Java 6 and earlier, it depends on the parent exception that you choose. Exceptions like Throwable, Exception and RuntimeException are far too general. If you catch these, you can end up accidentally catching (and then mishandling) exceptions that you should allow to propagate. For example, your code would catch NullPointerException that you should probably not attempt to recover from ... like that.
The first version is more correct / more robust than the second version, and that better even if it looks ugly.
Of course, the real answer depends on what happens after you have caught and logged the exception. If what happens next is appropriate for all exceptions, then the second version is (arguably) preferable. For instance, it could be appropriate to catch all exceptions, log them and then call System.exit(...).

Related

What's the meaning of "java class |" computation [duplicate]

This question already has answers here:
Can I catch multiple Java exceptions in the same catch clause?
(10 answers)
Closed 1 year ago.
public void run() {
final V value;
try {
value = getDone(future);
} catch (ExecutionException e) {
callback.onFailure(e.getCause());
return;
} catch (RuntimeException | Error e) {
callback.onFailure(e);
return;
}
callback.onSuccess(value);
}
I think the "|" computation is a kind of bit computation, and it can be applied to byte, int, long and so on. But what's the meaning when "|" symbol applied to some java classes?
RuntimeException | Error e
It is to catch multiple exceptions inside a single catch block
try{
}
catch(Exception1 | Exception2 | Exception2 e){
callSomething()
}
equivalent to :
try{
}
catch(Exception1 e){
callSomething()
}
catch(Exception2 e){
callSomething()
}
catch(Exception3){
callSomething()
}
this
catch (RuntimeException | Error e) {
means you are actually defining a block for catching either a RuntimeException OR an Error
that was introduced since java7
here more info about it:
https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
the explained pretty well
Consider the following example, which contains duplicate code in each of the catch blocks:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
In releases prior to Java SE 7, it is difficult to create a common method to eliminate the duplicated code because the variable ex has different types.
The following example, which is valid in Java SE 7 and later, eliminates the duplicated code:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}

How to catch two or more Exceptions in JAVA?

how can i catch 2 or more exception in same time ? Should i use trycatch-block for each all issue ?
For example, i couldn t catch b.charAt() to "Null Pointer Exception" after arithmeticException.
try{
int a = 6 / 0 ;
String b = null;
System.out.println(b.charAt(0));
}
catch(NullPointerException e){
System.out.println("Null Pointer Exception");
}
catch(ArithmeticException e){
System.out.println("Aritmetic Exception ");
}
In Java SE 7 and later, you actually can catch multiple exceptions in the same catch block.
To do it, you write it this way:
try{
// Your code here
} catch (ExampleException1 | ExampleException2 | ... | ExampleExceptionN e){
// Your handling code here
}
Besides that, you can use an extremely general catching exception like:
try{
// code here
} catch (Exception e){
// exception handling code here
}
But, that is a discouraged practice. ;)
Resources: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html (Oracle Documentation).

why bitwise or is used here in catch block to handle the exception in java?

Why bitwise or is used here?
try
{
//some errorprone code
}
catch(NullPointerException |NumberFormatExceptioon e)
{
////handling the exception
}
That's not a bitwise operator in this case. It's the syntax of catching multiple exceptions.
Feature added in Java 7.
https://docs.oracle.com/javase/8/docs/technotes/guides/language/catch-multiple.html
The catch clause specifies the types of exceptions that the block can handle, and each exception type is separated with a vertical bar (|).
Before java 7, you need write
try{
//some errorprone code
}catch (NullPointerException ex) {
//handle
} catch (NumberFormatExceptioon ex) {
//handle
}
Look, they simplified it right ?

Java 1.6 : Learn how to handle exceptions

I did extensive research on exceptions, but I'm still lost.
I'd like to know what is good to do or not.
And I'd also like you to give me your expert opinion on the following example :
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
} catch (IOException e) {
log.error("step1", e);
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Is it ok to throw a personnal exception (MyProcessException) in each step in order to manage a global try...catch...finally ?
Is it ok to manage each known exception for each step ?
Thank you for your help.
EDIT 1 :
Is it a good practice like this ? log directly in global catch by getting message, and try...catch(Exception) in upper level....
The purpose is to stop if a step fail, and to finalize the process (error or not).
In Controller
public void callProcess() {
try {
myprocess(...);
} catch (Exception e) {
log.error("Unknown error", e);
}
}
In Service
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
log.info("ok");
} catch (IOException e) {
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
log.error(mpe.getMessage(), mpe);
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Thank you.
Edit 2 :
Is it a real bad practice to catch (Exception e) in lower level and to throws a personnal exception ?
Doesn't exist a generic rule,it depends on your needs.
You can throw a personal exception, and you can manage each known exception.
But pay attention, it is important what you want.
try{
exec1();
exec2(); // if exec1 fails, it is not executed
}catch(){}
try{
exec1();
}catch(){}
try{
exec2(); // if exec1 fails, it is executed
}catch(){}
In your example above it may well be acceptable to throw your own custom exception.
Imagine I have some data access objects (DAO) which come in different flavours (SQL, reading/writing to files etc.). I don't want each DAO to throw exceptions specific to their storage mechansim (SQL-related exceptions etc.). I want them to throw a CouldNotStoreException since that's the level of abstraction that the client is working at. Throwing a SQL-related or a File-related exception would expose the internal workings, and the client isn't particular interested in that. They just want to know if the read/write operation worked.
You can create your custom exception using the originating exception as a cause. That way you don't lose the original info surrounding your problem.
In the above I probably wouldn't handle each exception in each step as you've done. If processing can't continue after an exception I would simply wrap the whole code block in an exception handling block. It improves readability and you don't have to catch an exception and then (later on) check the processing status to see if you can carry on as normal (if you don't do this you're going to generate many exceptions for one original issue and that's not helpful).
I would consider whether multiple catch {} blocks per exception add anything (are you doing something different for each one?). Note that Java 7 allows you to handle multiple exception classes in one catch{} (I realise you're on Java 6 but I note this for completeness).
Finally perhaps you want to think about checked vs unchecked exceptions.
The main point of the exception mechanism is to reduce and group together handling code. You are handling them in the style typical for a language without excptions, like C: every occurrence has a separate handling block.
In most cases the best option is to surround the entire method code with a catch-all:
try {
.... method code ...
}
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
The only times where this is not appropriate is where you want to insert specific handling code, or wrap in a custom exception that will be specifically handled later.
Most exceptions, especially IOExcption in your case, represent nothing else but failure and there will be no handling beyond logging it and returning the application to a safe point, where it can process further requests. If you find yourself repeating the same handling code over and over, it's a signal that you are doing it wrong.
One very important rule: either handle or rethrow; never do both. That is what you are doing in your example: both logging and rethrowing. Most likely the rethrown exception will be caught further up in the call stack and logged again. Reading through the resulting log files is a nightmare, but unfortunately quite a familiar one.
int step = 0;
try
{
step = 1;
...
step = 2;
...
step = 3;
...
}
catch (Exception1 e)
{
log ("Exception1 at step " + step);
throw new MyException1 ("Step: " + step, e);
}
catch (Exception2 e)
{
log ("Exception2 at step " + step);
throw new MyException2 ("Step: " + step, e);
}
...
I'd say it depends on your needs...
If step2 can execute correctly even if step1 failed, you can try/catch step1 separately.
Otherwise, I would group all steps in one try/catch block and made sure that the individual steps produce a log message when they fail.
That way you don't litter your code and still know what went wrong
It's ok to catch each known exception, so you can log what exception occure, and why it did.
Here some links to exception handling patterns/anti-patterns:
Do:
http://www.javaworld.com/jw-07-1998/jw-07-techniques.html
Don't:
http://today.java.net/article/2006/04/04/exception-handling-antipatterns
http://nekulturniy.com/Writings/RebelWithoutAClause/Rebel_without_a_clause.html
About creating your own exceptions, it's certainly useful if you're creating an API, a framework or another piece of reusable code, but in a regular application, it's more debatable and I personally would suggest to stick to existing exceptions.

Java catching exceptions and subclases

Hello,
In Java if a method like BufferedReader.read() says it can throw an IOException and I try to catch a FileNotFoundException and an IOException in two catch blocks, what catch blocks will be entered if the file doesn't exist?
Does it enter only the most specific or both?
The first coded catch that matches the exception will be entered.
Edited to incorporate comment from Azodius
For example:
try {
bufferedReader.read();
} catch (FileNotFoundException e) {
// FileNotFoundException handled here
} catch (IOException e) {
// Other IOExceptions handled here
}
This following code does not compile:
try {
bufferedReader.read();
} catch (IOException e) {
// All IOExceptions (and of course subclasses of IOException) handled here
} catch (FileNotFoundException e) {
// Would never enter this block, because FileNotFoundException is a IOException
}
Compiler message says:
Unreachable catch block for FileNotFoundException. It is already handled by the catch block for IOException
Only the first catch block encountered where the exception type of the catch block matches the type of the exception being thrown will be run (more specifically, the first catch block where (e instaceof <exception type>)==true will be run). None of the other catch blocks will be run.
For example
try{
BufferedReader.read();
}
catch(FileNotFoundException e){System.out.println("FileNotFoundException");}
catch(IOException e){System.out.println("IOException");}
Will print FileNotFoundException if BufferedReader.read() throws a FileNotFoundException.
Note that the following doesn't actually compile:
try{
BufferedReader.read();
}
catch(IOException e){System.out.println("IOException");}
catch(FileNotFoundException e){System.out.println("FileNotFoundException");}
because Java realizes that it is not possible for the FileNotFoundException to be caught because all FileNotFoundExceptions are also IOExceptions.
The first one which is suitable for that type of exception (and only that). So if you catch the two exception types above in the order you list them, a FileNotFoundException will be caught.
Specific exception is caught first. and it's a compile time error if generic exception is caught befor specific one.

Categories

Resources