Exception handling continue on error and then rethrow - java

//Assume list1 and list2 are populated with states as 2
foo (List<Class1> list1, List <Class1> list2) {
boolean error = false;
try {
operate on list1
} catch (Exception e) {
error = true;
//Modify list1 objects to state 1
}
try {
operate on list2
} catch (Exception e) {
error = true;
//Modify list2 objects to state 1
}
//What are the problems and what is the best practice for this
if (error)
throw new Exception(…); //How should i really rethrow the exception
}

The main improvement I'd make is to store all exceptions that occur and make them available somehow, somewhere. Otherwise, it seems fine.
To the skeptical, it's not really abnormal to want to complete some work even when an exception happens. Batch processing is a pretty typical case.

Nothing technically wrong with it, other than getting the throws clause correct, etc. You could even save one of the caught exceptions and re-throw it.
Not clear why you'd want to do this, but I've done weirder.

Related

method.invoke dynamic exception throwing

short Summary : I want to create a wrapper/Interceptor for our java clients making external call and we have a lot of different java clients so I don't want to map exception one by one.
public Object handleRequest(Object delegate, Method method, Object[] objects) {
Object result = null;
try {
result = method.invoke(delegate, objects);
// do some logic
} catch ( IllegalAccessException | IllegalArgumentException e) {
// do nothing
} catch (InvocationTargetException e) {
throw e.getCause(); //java: unreported exception java.lang.Throwable; must be caught or declared to be thrown
}
return result;
};
};
}
In the code above, what I would like to do is throw the exception that the delegate is throwing (which would be obtainable by getting e.getCause(), but it is throwable). Since we have many maaany clients, I want to avoid checking it with many if and else statements and checking with isInstanceOf() (or other variations of it). Is there a way for me to throw the whatever e.getCause() as type of that specific type programatically?
No. If you are handed an arbitrary Method, you can't make the caller know what particular type of exception that method throws. You can of course throw Throwable and just throw e.getCause(), but it sounds like that's what you don't want to do -- but there's no way around it given the rest of your design.
You could move away from reflection and use interfaces and method references, but it's not clear from the context how feasible that is.

why is the Catch exception e printing instead of doing what is in Try

I am confused why it is going to catch and print the error occurred message when I run my code since it runs and just prints the message I can't tell what the error could be
Note: this is my very first time using try and catch my professor told us to use it but haven't really learned how it works fully yet so I'm not sure if the problem is with that or if it's just with my code
public static void main (String [] args) {
try {
File file = new File("in.txt");
Scanner scanFile = new Scanner(file);
...
} catch(Exception e) {
System.out.println("Error");
}
}
Do not catch an exception unless you know what to do. It is common that you don't - most exceptions aren't 'recoverable'.
So, what do you do instead?
Simplest plan: Just tack throws Exception on your main method. public static void main(String[] args) methods should by default be declared to throws Exception, you need a pretty good reason if you want to deviate from this.
Outside of the main method, think about your method. Is the fact that it throws an exception an implementation detail (a detail that someone just reading about what the method is for would be a bit surprised by, or which could change tomorrow if you decide to rewrite the code to do the same thing but in a different way)? In that case, do not add that exception to the throws clause of your method. But if it is, just add it. Example: Any method whose very name suggests that file I/O is involved (e.g. a method called readFile), should definitely be declared to throws IOException. It'd be weird for that method not to throws that.
Occasionally you can't do that, for example because you're overriding or implementing a method from an interface or superclass that doesn't let you do this. Or, it's an implementation detail (as per 2). The usual solution then is to just catch it and rethrow it, wrapped into something else. Simplest:
} catch (IOException e) {
throw new RuntimeException("uncaught", e);
}
Note that the above is just the best default, but it's still pretty ugly. RuntimeException says very little and is not really catchable (it's too broad), but if you don't really understand what the exception means and don't want to worry about it, the above is the correct fire-and-forget. If you're using an IDE, it probably defaults to e.printStackTrace() which is really bad, fix that template immediately (print half the details, toss the rest in the garbage, then just keep on going? That's.. nuts).
Of course, if you know exactly why that exception is thrown and you know what to do about it, then.. just do that. Example of this last thing:
public int askForInt(String prompt) {
while (true) {
System.out.println(prompt + ": ");
try {
return scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("-- Please enter an integral number");
}
}
}
The above code will catch the problem of the user not entering an integer and knows what to do: Re-start the loop and ask them again, until they do it right.
Just add throws Exception to your main method declaration, and toss the try/catch stuff out.
There are a couple of problems with your current code:
catch (Exception e) {
System.out.println("Error occured...");
}
Firstly, you are not printing any information about the exception that you caught. The following would be better:
catch (Exception e) {
System.out.println(e.getMessage()); // prints just the message
}
catch (Exception e) {
System.out.println(e); // prints the exception class and message
}
catch (Exception e) {
e.getStackTrace(System.out); // prints the exception stacktrace
}
Secondly, for a production quality you probably should be logging the exceptions rather than just writing diagnostics to standard output.
Finally, it is usually a bad idea to catch Exception. It is usually better to catch the exceptions that you are expecting, and allow all others to propagate.
You could also declare the main method as throws Exception and don't bother to catch it. By default, JVM will automatically produce a stacktrace for any uncaught exceptions in main. However, that is a lazy solution. And it has the disadvantage that the compiler won't tell you about checked exceptions that you haven't handled. (That is a bad thing, depending on your POV.)
now null printed out.
This is why the 2nd and 3rd alternatives are better. There are some exceptions that are created with null messages. (My guess is that it is a NullPointerException. You will need a stacktrace to work out what caused that.)
Catching Exception e is often overly broad. Java has many built-in exceptions, and a generic Exception will catch all of them. Alternatively, consider using multiple catch blocks to dictate how your program should handle the individual exceptions you expect to encounter.
catch (ArithmeticException e) {
// How your program should handle an ArithmeticException
} catch (NullPointerException e) {
// How your program should handle a NullPointerException
}

Try Catch block works but test assertThrows fail (Junit 5)

I am trying to follow this tutorial JUnit 5: How to assert an exception is thrown?
I use Java 10, IntelliJ 2018 and Junit 5.
I make a calculator app that adds 2 fractions. It checks whether the input has 0 in the denominator.
When I run the test The exception Message get printed out "Undefined Math Expression" but my IDE says "Expected java.lang.Throwable to be thrown, but nothing was thrown." I think there is some problem with the scope of my code? I'm a newbie, please be kind. I provided the code and the test below:
public class Calculator {
public static int[] calculate (int firstNumerator, int firstDenominator, int secondNumerator, int secondDenominator) {
String exceptionMessage = "Undefined Math Expression";
int resultNumerator;
int resultDenominator;
int[] result = new int[2];
resultNumerator = (firstNumerator * secondDenominator) +
(secondNumerator * firstDenominator);
resultDenominator = firstDenominator * secondDenominator;
try {
if (resultDenominator == 0) {
throw (new Throwable(exceptionMessage));
} else {
result[0] = resultNumerator;
result[1] = resultDenominator;
}
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return result;
}
}
The test:
class CalculatorTest {
#Test
void denominatorContainsZero() {
assertThrows(Throwable.class, () -> {
Calculator.calculate(0,0,0,0);
});
}
}
The misunderstanding here appears to be in what JUnit can actually see.
JUnit isn't magical: it's just plain old Java. It can't see inside your methods to see what they are doing. All it can see is what any other code can see when it executes a method: the return value and uncaught exceptions (as well as any side effects of the method, if they are visible to the calling code).
Your method here doesn't throw an exception from the perspective of a caller: internally, it throws the exception, but it catches and handles it.
If you want JUnit to test that an exception is thrown, you need to not catch that exception.
It is never (*) the right thing to do to throw an exception and then catch and handle it yourself. What's the point? You can simply do the thing you do to handle it, without throwing the exception. Exceptions are expensive to throw, because of the need to capture the entire stack trace.
Throwable is never (*) the right exception to throw. It's the exception "equivalent" of returning Object: it conveys no type information about the exception to the caller, who then either has to do a lot of work to try to handle it; or, more realistically, should just propagate it themselves. IllegalArgumentException is the right exception to throw here, if you actually needed to throw (and not catch) an exception.
Throwable is rarely the right thing to catch. Throwable is a supertype of both Exception and Error, so you might unintentionally catch an Error, like OutOfMemoryError, which shouldn't be caught because there is nothing reasonable to do except crash your program. Catch the most specific type you can; which also means that you should throw the most specific type you can (or, at least, a type appropriate to the abstraction).
(*) This is "never" as in "ok, there are a limited number of circumstances where it may be appropriate". But unless you understand what these are, don't.
The Throwable is catched by try catch block, so Junit can not access it. Try remove the try catch block.
You are not actually throwing exception, you are catching it. For this to work, you should remove try catch block.

Can we catch UnsupportedOperationException

In the following example, I am able to get the resulted printed though was expecting a Runtime exception. Since I have used catch block , does it mean I am able to catch the unchecked exception too? if so than why can't we simple proceed by putting catch block where we suspect a runtime exception to occur.
Below is the code:
public class CollectionsSample {
public static void main(String args[]) /*throws UnsupportedOperationException*/{
Set<String> st = new HashSet<String>();
st.add("akkhil");
st.add("gupta");
Collection<String> coll = Collections.unmodifiableCollection(st);
try{
coll.add("changed");
}catch(Exception e){
//throw e;
}
for(String s : st){
System.out.println(" " + s);
}
}
This produces output as akkhil gupta though I was expecting it to through runtimeexcption at coll.add("changed");
does it mean I am able to catch the unchecked exception too?
Absolutely, you can. However, it does not mean that you should.
why can't we simple proceed by putting catch block where we suspect a runtime exception to occur?
We certainly can do that. However, this would be a wrong thing to do, because in a properly designed system runtime exceptions indicate programming errors. These errors need to be fixed in code, rather than caught. For example, if you do not know if a collection is modifiable or not, don't modify it without making a copy.

Nested or sequential exception handling?

I guess there isn't necessarily a 'right' answer to this, perhaps it's more a question of style but I often find myself wondering how to structure try/catch blocks.
For example take the two methods outlined in my hypothetical piece of code below (purely illustrative), I have a method that throws exceptions that I call multiple times but require different handling depending on which call it is. Similarly there could be different types of exception thrown with different handlers.
private Object exceptionMethod() throws Exception {
throw new Exception("Something bad happened");
}
public void useMethodSequentialHandlers() {
Object o1; // Must be declared in a wider scope than where it is used
try {
o1 = exceptionMethod();
} catch (Exception ex) {
// Assume we cannot continue after this exception so we'll return or
// rethrow to exit the method
return;
}
Object o2; // Must be declared in a wider scope than where it is used
// Do something that requires o1
for (int i = 0; i < 100; i++) {
try {
o2 = exceptionMethod();
// Here we would use the objects in some manner
boolean equal = o1.equals(o2);// Just a pointless example
// to show that both objects
// are required
// Assume the method does a load of stuff down here
} catch (Exception ex) {
// Assume we can continue to the next iteration after this exception
continue;
}
}
}
As I see it the advantage of having the try/catch blocks in a sequential order is that it is clearer to the reader exactly at what point I'm responding to the exception so perhaps there is better code clarity.
The disadvantages would be that we have exception handling littered around various places in the method and we have variables declared in a wider scope than required (is this a bad thing?).
Alternatively:
public void useMethodNestedHandlers() {
try {
Object o1 = exceptionMethod(); // Can be declared inside scope where it is used
// Do something that requires o1
for (int i = 0; i < 100; i++) {
try {
Object o2 = exceptionMethod(); // Can be declared inside scope where it is used
// Here we would use the objects in some manner
boolean equal = o1.equals(o2); // Just a pointless example
// to show that both objects
// are required
// Assume the method does a load of stuff down here
} catch (Exception ex) {
// Assume we can continue to the next iteration after this
// exception
continue;
}
}
} catch (Exception ex) {
// Assume we cannot continue after this exception so we'll return or
// rethrow to exit the method
return;
}
}
Here we keep exception handling logic together and variables are declared within the scope they're used. However to me the exception handling logic seems less clear as it is further from it's point of origin.
Does anyone have an opinion on which would be better or am I just worrying about pointless minutiae and should just get on with my job? :-)
Thanks
I would prefer both depends the condition.
Case 1
Object obj;
try {
// do something
} catch (Exception e) {
obj = default_obj; // assign default object
}
try {
// do something either with specific or default object
} catch (Exception e) {
// handle exception
}
Here even if the first try catch fails , proceed the action with default value
Case 2
try {
Object obj;
// acquire object
// do something only if acquire object is successful
} catch (Exception e) {
// handle exception
}
Here do not proceed further when acquire object isn't successful.
Here it is way of handling exception is more of a necessity than a style.
I believe that in all cases were the answer does not clearly arise from technical analysis one should ignore the initial development work and study the future of the code.
To this end I would advise the first method as the best choice unless there is a real technical reason to choose the second.
In summary:
If there is no technical difference between two styles, consider the future reader of your code and make it as obvious as possible.
The beauty of exceptions is that you don't have to handle them where they occur. That's why you should in fact use your second style, but without the outer try-catch:
public void useMethodNestedHandlers() {
Object o1 = exceptionMethod(); // Can be declared inside scope where it is used
// Do something that requires o1
for (int i = 0; i < 100; i++) {
try {
Object o2 = exceptionMethod(); // Can be declared inside scope where it is used
// Here we would use the objects in some manner
boolean equal = o1.equals(o2); // Just a pointless example
// to show that both objects
// are required
// Assume the method does a load of stuff down here
} catch (Exception ex) {
// Assume we can continue to the next iteration after this
// exception
continue;
}
}
}
Code for the happy-day scenario and let someone else worry about failures. That's the way to achieve separation of concerns: usually all failures are treated by the same piece of code and catching too early breeds duplicated code.
the code should be 1) correct, 2) readable. usually all irrecoverable exception should be handle in highest layer of application (or not at all). that means they should be properly displayed to the user. all recoverable exceptions should be handle 'as high' as possible. i advise to use as few try-catch statements as possible

Categories