Custom Exception that wraps Multiple Exceptions : Encouraged or Not? - java

I am coding a Java Library that will be used to access a DB.
I am throwing the exceptions to the end-programmer who uses the JAR library to handle it the way he/she wants.
I wrote a custom Exception (provided below) to wrap connection specific exceptions together so the end-programmer will not have to catch all these exceptions in his code. (to make it easy for him)
is this a good practice when it comes to coding Java libraries?
By using this the user will only have to catch NConnectionException in his code.
public class NConnectionException extends Exception {
private static final Logger logger = LoggerFactory.getLogger(NConnectionException.class);
public NConnectionException(Exception e) {
if (e instanceof NullPointerException) {
logger.error("ERROR IN READING DF");
e.printStackTrace();
}
else if (e instanceof FileNotFoundException) {
logger.error("FILE NOT FOUND");
e.printStackTrace();
} else if (e instanceof ParserConfigurationException)
{
logger.error("PARSE CONF ERR");
e.printStackTrace();
}
else if (e instanceof org.xml.sax.SAXException)
{
logger.error("SAX ERR");
e.printStackTrace();
}
else if (e instanceof IOException)
{
logger.error("IO ERR");
e.printStackTrace();
}
}
}

You can pass a cause (Throwable) to a custom exception. Look at the Exception javadoc for more Information.
Edit:
public class CustomException extends Exception {
public CustomException(Throwable t) {
super(t);
}
}
public void testMethod(String s) throws CustomException {
try {
int integer = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new CustomException(e);
}
}
try {
testMethod("not a number");
} catch (CustomException ce) {
ce.printStackTrace(); // this will print that a CustomException
// with the cause NumberFormatException has occured.
ce.getCause(); // this will return the cause that
// we set in the catch clause in the method testMethod
}

According to this post, wrapping all the exceptions in a single is not good.
If you want to wrap them then
As your program will throw only one exception at a time then no need to store list of exceptions in NConnectionException.
And you can create a single object of exception in NConnectionException class. You can refer this structure.
And store the thrown exception in that object and throw back newly created object of NConnectionException class. Let the calling program catch NConnectionException exception and take out the stored object and act accordingly.
Note : Generally we don't handle unchecked exception (like NullPointerException), calling program will take care of it.

Related

How is multiple exception handling done in java? [duplicate]

This question already has answers here:
Exception Handling with Multiple catch block [duplicate]
(2 answers)
Can I catch multiple Java exceptions in the same catch clause?
(10 answers)
Closed 4 years ago.
i have below piece of code which in my spring boot applicatin. This piece of code does email validation,
class EmailValidation {
public static void validate(List<String> s){
try {
for (String address : s) {
if (s == null || s.indexOf("#") < 0) {
throw new InvalidEmailAddressException("Email address is invalid ");
}
new InternetAddress(s);
}
} catch(AddressException e){
LOGGER.Error("Please validate email addresses");
}
}
}
class InvalidEmailAddressException extends RuntimeException {
public InvalidEmailAddressException(String message) {
super(message)
}
}
My question is how do I catch InvalidEmailAddressException? How can i achieve it to handle the exception in this piece of code itself and how it will be handled by the caller?
Use the multi-catch block like so:
try {
stuff
} catch (AddressException | InvalidEmailAddressException ex) {
handle exception
}
There're 2 types of exceptions: checked, unchecked.
InvalidEmailAddressException extends RuntimeException which is unchecked exception that you shouldn't catch, so better extend it from Exception class.
As an alternative to SnakeyHips' answer, you can provide several catch blocks separately, like
try {
// do what you have to do here
} catch (AddressException) {
LOGGER.Error("AddressException thrown");
} catch (InvalidEmailAddressException ex) {
LOGGER.Error("InvalidEmailAddressException thrown");
}
Firstly I think it is not good practice to extend from RuntimeException, that exception means that program crashes, you should extend from Exception. My opinion you should read some more about exceptions in Java. If your method does not catch exception you should put in method signature that method throws specific exception, something like:
public static void validate(List s) throws InvalidEmailAddressException {
... }
Then make this one:
class InvalidEmailAddressException extends Exception{
public InvalidEmailAddressException(String message){
super(message)
}
And that catch method, about AddressException you do not have it definition here, and I think if you want this to be proceed to caller you should not catch it at all, just declare in throws.
SnakeyHips' answer is solid but be aware that you will not able to react differently to different exceptions.
try {
//your code
} catch (AddressException e1) {
//handle this exception
} catch (InvalidAdressException e2) {
//handle this exception
}
This will enable you to handle the exceptions differently. If you dont care about this you may aswell just catch the general Exception class:
try {
//your code
} catch (Exception e) {
//handle exception
}

How to handle Exception properly from a method?

Suppose, I have a method:
private void someMethod() {
try {
//Do something here
}
catch (NullPointerException ex) {
System.out.println("error");
}
}
Now, I want to use this method somewhere else:
private void newMethod() {
someMethod();
JOptionPane.showMessageDialog(null, "Exception didn't occur");
}
Now, I want that if exception occurs in someMethod(), then newMethod() will not advance further, I mean, the JOptionPane message will not be shown in this case.
What will be the best way to do that? I have found a way by throwing another NullPointerException in catch block of someMethod() and then handling that from newMethod(). The code below demonstrates that:
private void someMethod() {
try {
//Do something here
}
catch (NullPointerException ex) {
System.out.println("error");
throw new NullPointerException("error");
}
}
private void newMethod() {
try {
someMethod();
JOptionPane.showMessageDialog(null, "Exception didn't occur");
}
catch (NullPointerException ex) {
System.out.println("error");
}
}
But, by this method, I am facing some difficulties for other cases. I guess there are better ways to achieve that. Thanks anyway.
You don't need to handle the exception inside someMethod. Instead you can declare the exception in this method's throws clause (if it is a checked exception) and let newMethod handle it.
private void someMethod() throws SomeCheckedException {
//Do something here
}
In case of NullPointerException, you don't need to do above, as it is an unchecked exception. Don't catch it inside someMethod, instead have try-catch inside newMethod.
It is good practice if your function intend to throw exception make it part of function declaration. So recommendation is to change someMethod() to private void someMethod() throws <exception Name>.
Depends on your requirement you can handle the exception in same method and throw another exception, or re throw same exception and handle it in another function.
In case you are re-throwing the same exception syntax is as follows:
private void someMethod() throws WhateverException {
try {
//Do something here
}
catch (WhateverException e) {
throw e;
}
}

Custom exception in java

I have a simple exception and I don't know how to deal with it. My question is what should I do in main?
I know I should create an Exception Class but that's a simple example to understand how should the exceptions be treated in main.
In main I want do display a message and exit the program and I don't understand how to do it.
public void addProfessor() throws Exception {
if(professor) {
throw new Exception(" prof already exists");
}
else {
professor=true;
System.out.println("\n--- addProfessor ---");
System.out.println("Professor: " + professor);
superState=SuperState.OPEN;
System.out.println(superState);
subState=SubState.ASSIGNED;
System.out.println(subState);
}
}
try {
C.addProfessor();
C.addProfessor();//here an exception should be displayed because I should have only one professor
} catch(Exception e) {
e.printStackTrace();
}
finally {
}
First of all your example looks like the exception you are trying to use is thrown in standard buisness flow.
It's good practice to keep exceptions to handle really exceptional cases, and not use it in a program flow.
If it's just an example then:
First: (as mentioned in one of comments) better create your own exception (just derive for example from RuntimeException if you want unchecked
or from Exception for checked one) - then you will not catch some other unexpected exception by accident.
Second: when you catch the exception then you have a choice what to do:
do some cleanup & rethrow
just log it
you can also re-try if it makes sense (in your example it does not, because re-trying will just throw another exception - unless the profesor has been removed by another thread)
When you catch the exceptin instead of e.printStackTrace(); you can get a message from the exception or even (as you created your own meaningful exception) you already know the root cause and can just display it to the user.
just an ilustration:
catch(ProfessorAlreadyExistsException e) {
System.out.println("Professor already exists");
}
To create a custom Exception you need to create a class that extends Exception. For example as follow:
public class ProfessorException extends Exception {
public ProfessorException(String msg) {
super(msg);
}
}
Then you need to use this ProfessorException in your code:
public void addProfessor() throws ProfessorException {
if(professor) {
throw new ProfessorException(" prof already exists");
}
...
}
...
try {
C.addProfessor();
C.addProfessor();//here an exception should be displayed because I should have only one professor
} catch (ProfessorException e) {
e.printStackTrace();
} finally { // Note that finally block is not needed here because it does nothing
}
If you want to display a message on standard output instead of printing the stack trace you can do that:
try {
C.addProfessor();
C.addProfessor();//here an exception should be displayed because I should have only one professor
} catch (ProfessorException e) {
System.out.println(e.getMessage());
}

Replacing generic exceptions with more specific exception types?

For a project I've been working on, we have some blocks that look like this:
Class A:
try {
callSomeMethod();
}
catch (Exception e) {
throw new SomeCustomExceptionTypeForMetrics("");
}
However, I was tasked with replacing all instances where we catch generic exceptions with only specific "expected" types of exceptions.
The problem is callSomeMethod() has something like this
Class B:
try {
if (someCondition...) {
}
else {
//failed
throw new RuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new RuntimeException("Something here");
}
Ideally, my group has asked me to change as little as possible, and I can't change the signature for callSomeMethod(), but they also don't want to just catch any RuntimeException in Class A since they don't want to catch just any type of RuntimeException - only the ones we're excepting from Class B.
What is the best way to handle this?
Supposing that your callSomeMethod's signature contains throws Exception, and you can't change it: Change the RuntimeExceptions in the method to a custom Exception class, and then in Class A:
try {
callSomeMethod();
}
catch (Exception e) {
if(e instanceof CustomException)
//Log it or something, for metrics?
}
This is kind of silly, but might be necessary if you can't change the method signature. (If you can change it, you could catch the CustomException directly.) You could even make a method in your logger that takes an Exception, checks what type it is, and acts accordingly. Then just use this method in every catch statement that you need to edit.
While designing this solution, keep in mind that RuntimeExceptions don't need to be caught. It could save you some trouble.
If you chnage your code in class B as below
try {
if (someCondition...) {
}
else {
//failed
throw new MyRuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new MyRuntimeException("Something here");
}
and define MyRuntimeException as :
class MyRuntimeException extends RuntimeException{
..
}
In class A, you only need to catch MyRuntimeException exception .
Hope this solve your problem!!

Exception already caught error

Here's the code:
public class Exc {
int x = 2;
public void throwE(int p) throws Excp, Excp2 {
if(x==p) {
throw new Excp();
}
else if(x==(p+2)) {
throw new Excp2();
}
}
}
Here's the handler code:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
System.out.println("Caught ya!");
} catch(Exception Excp2) {
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
Excp and Excp2 both extends Exception and have similar code(nothing). Now I'm getting the error Exception has already been caught error at Excp2, regardless of whether I supply 2 or 0 to throwE method.
You're looking for:
try
{ }
catch(Excp excp)
{
log(excp);
}
catch(Excp2 excp2)
{
log(excp2);
}
finally
{ }
When you catch an exception, to specify the type of the exception, and the name of of its reference.
Your original code tried to catch Exception, which is the least specific exception, so you cannot catch anything after that.
When you are catching an exception, you have to specify what type of exception you are catching, this will allow you to better handle the exception that has occured. One thing that you have to keep in mind though, is that there is that there are specific and other more "wide purpose" exceptions.
For instance, NumberFormatException is more specific than Exception, since NumberFormatException will be thrown whenever you will try to parse a string into a number.
Thus, when having multiple catch statements, always put the most specific one on top, and the more generic ones at the end. If you put the more generic ones at the beginning, they will catch the exception before it can be passed to a more specific catch statement.
In your case, you are trying to catch the same exception twice, since you have two catch statements that try to catch the same exception.
Java dispatches to the catch() clauses based on the types of the exception: your clauses are both trying to catch an exception of type Exception, and give them the names Excp and Excp2:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
Shouldn't this be Excp e?
System.out.println("Caught ya!");
} catch(Exception Excp2) {
Shouldn't this be Excp2 e?
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
And, while it's unrelated, I think your earlier code would be easier for you to think about if you write it more like this:
public void throwE(boolean p) throws Excp, Excp2 {
if(p) {
throw new Excp();
} else {
throw new Excp2();
}
}
Call it with true or false as parameters.
I believe the exception can only be caught once with java. The first exception handler will process the error.
Please someone tel me if this is true for java :)

Categories

Resources