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;
}
}
Related
I wrote an example which depicts my issue.
I have a simple exception:
public class TryToSpeakException extends RuntimeException {
public TryToSpeakException(String message) {
super(message);
}
}
Then I have a chain of methods that invoke each other one by one:
public class TryToSpeak {
public static void speakToPerson1() {
throw new TryToSpeakException("Person 1 don't wanna speak to anyone.");
}
public static void speakToPerson2() {
try {
speakToPerson1();
} catch (Exception e) {
System.out.println("speakToPerson2 caused exception");
e.printStackTrace();
}
}
public static void speakToPerson3() {
try {
speakToPerson2();
} catch (Exception e) {
System.out.println("speakToPerson3 caused exception");
e.printStackTrace();
}
}
static void keepSilentToPerson() {
System.out.println("Keeping silent to person 1");
}
public static void communicate() {
try {
speakToPerson3();
keepSilentToPerson(); // Why it reaches this part?
} catch (Exception e) {
System.out.println("Communication exception.");
e.printStackTrace();
}
}
public static void main(String[] args) {
communicate();
}
}
The method from the very 'bottom' throws an exception. In method communicate() after invocation of method speakToPerson3() the execution keeps going.
What i need - is to Stop execution, so that invocation of method keepSilentToPerson() is never reached and gives me the message "Communication exception.".
This is what i get in console now:
speakToPerson2 caused exception
exceptions.TryToSpeakException: Person 1 don't wanna speak to anyone.
at exceptions.TryToSpeak.speakToPerson1(TryToSpeak.java:7)
at exceptions.TryToSpeak.speakToPerson2(TryToSpeak.java:12)
at exceptions.TryToSpeak.speakToPerson3(TryToSpeak.java:22)
at exceptions.TryToSpeak.communicate(TryToSpeak.java:36)
at exceptions.TryToSpeak.main(TryToSpeak.java:46)
Keeping silent to person 1
But if i call speakToPerson2() from my Main method like this:
public static void speakToPerson1() {
throw new TryToSpeakException("Person 1 don't wanna speak to anyone.");
}
public static void speakToPerson2() {
try {
speakToPerson1();
keepSilentToPerson();
} catch (Exception e) {
System.out.println("speakToPerson2 caused exception");
e.printStackTrace();
}
}
static void keepSilentToPerson() {
System.out.println("Keeping silent to person 1");
}
public static void main(String[] args) {
speakToPerson2();
}
I get an obvious result:
speakToPerson2 caused exception
exceptions.TryToSpeakException: Person 1 don't wanna speak to anyone.
at exceptions.TryToSpeak.speakToPerson1(TryToSpeak.java:7)
at exceptions.TryToSpeak.speakToPerson2(TryToSpeak.java:12)
at exceptions.TryToSpeak.main(TryToSpeak.java:26)
keepSilentToPerson() is not reached.
What am i doing wrong?
speakToPerson2() is catching the Exception, but you want communicate() to catch it too. Essentially, speakToPerson2() is suppressing the exception, so no other method sees it.
What you need to do is rethrow it (in both speakToPerson2() and speakToPerson3()). This is known as propagating an exception.
I.e.:
public static void speakToPerson2() {
try {
speakToPerson1();
} catch (Exception e) {
System.out.println("speakToPerson2 caused exception");
e.printStackTrace();
throw e;
}
}
public static void speakToPerson3() {
try {
speakToPerson2();
} catch (Exception e) {
System.out.println("speakToPerson3 caused exception");
e.printStackTrace();
throw e;
}
}
You need to understand exactly how try-catch work. If any method in the try-catch throws an exception (one that extends/or is Exception in your example), the body of the try-catch will be interrupted to go into the catch clause.
In your case, the method speakToPerson1 will throw a TryToSpeakException. This exception will be forwarded one step above in the method call stack, the method speakToPerson2 in your case. Since the call to speakToPerson1 is surrounded with a try-catch, the catch clause is invoked and System.out.println("speakToPerson2 caused exception"); is executed. Now, the try clause encloses two methods calls, namely speakToPerson1 and keepSilentToPerson. However, since the first method throw the exception, the second is never reached and therefore keepSilentToPerson() will never by called.
Finally, think about the catching of exceptions. If you catch an exception, you are saying that you are going to handle it, by recovering or rethrowing it. If you handle it without rethrowing it, it won't be forwarded to the upper level of your call stack. Beware of this technicality
You can throw the exception after catching it speakTo* methods. This will stop execution of code in methods calling speakTo* and their catch block will be executed.
catch (Exception e) {
System.out.println("speakToPerson2 caused exception");
e.printStackTrace();
throw e;
}
You need to propagate your Exceptions to the main class to completely stop the execution of a program.
In the case 1: All your exception will be handled by speakToPerson2 function.
In the case 2: Your exception occurs at the function call of speakToPerson1, so the rest of your code will not execute.
So, inorder to stop the program from running you just have to propagate the exception, using throw keyword, in the catch block of your exception.
I am a C programmer and just learning some java recently because I am developing one android application. Currently I am in a situation. Following is the one.
public Class ClassA{
public ClassA();
public void MyMethod(){
try{
//Some code here which can throw exceptions
}
catch(ExceptionType1 Excp1){
//Here I want to show one alert Dialog box for the exception occured for the user.
//but I am not able to show dialog in this context. So I want to propagate it
//to the caller of this method.
}
catch(ExceptionType2 Excp2){
//Here I want to show one alert Dialog box for the exception occured for the user.
//but I am not able to show dialog in this context. So I want to propagate it
//to the caller of this method.
}
}
}
Now I wan to use call the method MyMethod() somewhere else in another class. If some one can provide me some code snippet how to propagate the exceptions to the caller of MyMethod() so that I can display them in a dialog box in the caller method.
Sorry If I am not so much clear and weird in the way of asking this question.
Just don't catch the exception in the first place, and change your method declaration so that it can propagate them:
public void myMethod() throws ExceptionType1, ExceptionType2 {
// Some code here which can throw exceptions
}
If you need to take some action and then propagate, you can rethrow it:
public void myMethod() throws ExceptionType1, ExceptionType2 {
try {
// Some code here which can throw exceptions
} catch (ExceptionType1 e) {
log(e);
throw e;
}
}
Here ExceptionType2 isn't caught at all - it'll just propagate up automatically. ExceptionType1 is caught, logged, and then rethrown.
It's not a good idea to have catch blocks which just rethrow an exception - unless there's some subtle reason (e.g. to prevent a more general catch block from handling it) you should normally just remove the catch block instead.
Don't catch it and rethrow again. Just do this and catch it in the place you want
public void myMethod() throws ExceptionType1, ExceptionType2 {
// other code
}
Example
public void someMethod() {
try {
myMethod();
} catch (ExceptionType1 ex) {
// show your dialog
} catch (ExceptionType2 ex) {
// show your dialog
}
}
Just rethrow the exception
throw Excp1;
You will need to add the exception type to the MyMthod() declaration like this
public void MyMethod() throws ExceptionType1, ExceptionType2 {
try{
//Some code here which can throw exceptions
}
catch(ExceptionType1 Excp1){
throw Excp1;
}
catch(ExceptionType2 Excp2){
throw Excp2;
}
}
Or just omit the try at all since you are no longer handling the exceptions, unless you put some extra code in the catch statements doing things with the exception before rethrowing it.
I always do it like this :
public void MyMethod() throws Exception
{
//code here
if(something is wrong)
throw new Exception("Something wrong");
}
then when you call the function
try{
MyMethod();
}catch(Exception e){
System.out.println(e.getMessage());
}
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
}
I have a method. This method has a catch block.
// pseudo code
private void function() {
try {
// something
} catch(exception e) {
// error handling
}
}
This method is called in another class
In one scenario the class is implemented with its own catch block
// pseudo code
private void anotherFunction() {
try {
function();
} catch {
//another catch block
}
Now I just want to execute the code in the catch block where the function is called and don't call the catch block implemented in the class. Is there a way to do this or should I think about another approach?
A workaround is to move your logic to another method which doesn't handle that exception, but just passes it upwards e.g:
public void unsafeFunction() throws Exception{
// something
}
And then call that method from your both classes, where both handle the exception differently:
public void function(){
try {
unsafeFunction();
} catch(Exception e){
// error handling
}
}
And:
public void anotherFunction(){
try {
unsafeFunction();
} catch(Exception e){
// other error handling
}
}
That way you leave what should be done with the exception to the caller.
Another completly different approach is to use the java.util.function.Consumer interface from Java 8 and accept that in your function, the caller then can just pass the error-handler into it:
public void function(Consumer<? super Exception> errorHandler){
try{
// something
} catch(Exception e){
// delegate to handler
errorHandler.accept(e);
}
}
Which can then be used like this:
public void someFunction(){
function(e -> {
// error handling
});
}
And:
public void anotherFunction(){
function(e -> {
// other error handling
});
}
There must be a reason to catch the exception. Say that reason can be tested in a separate method:
private boolean testCircumstanceThrowingException() {
if (exceptionalCircumstance) {
return false;
} else {
return true;
}
}
then you can implement your original function as:
private void functionCatchingException(){
if (testCircumstanceThrowingException()) {
//error handling
}
function();
}
and
private void anotherFunction() {
if (testCircumstanceThrowingException()) {
//error handling
}
function();
}
this way, during the normal running of the application, no exceptions are thrown. And this is how it should be because exceptions are for exceptional circumstances. If you somehow get to a state where exceptions are expected then something is wrong.
You should only rely on excpetions if there is no other way. For instance, if your specific use of the function cannot test the exceptional circumstance and you're required to use function. Take a look at Lino's answer for possible workarounds.
Java purists will notice that you can simply do return exceptionalCircumstance; but this code was just intended to show that a function that tests for the exceptional circumstance may be required; the result may not even be a boolean.
Of course you may now want to rename functionCatchingException :)
In your first code snippet:
private void function() {
try {
// something
}
catch (Exception e) {
// error handling
throw e; // rethrow?
}
}
you basically have two options with Java. You can either swallow the exception, or you can rethrow it. If you swallow it, then the caller of this method won't see an exception. If you rethrow, then the caller would also get an exception.
If neither of these behaviors are what you really want, then you might want to rethink your design.
You can throw the exception to the caller method using the keyword throw:
private void function(){
try{
//something
} catch(Exception e){
//error handling
throw e;
}
}
Then your anotherFunction() catch block will be executed.
You can learn more from here: The Java Tutorials
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 :)