Handling Checked and unchecked exceptions? - java

I have below class with one method which throws Checked Exception.
public class Sample{
public String getName() throws CustomException{
//Some code
//this method contacts some third party library and that can throw RunTimeExceptions
}
}
CustomException.java
public class CustomException Extends Exception{
//Some code
}
Now in another class i need to call above the method and handle exceptions.
public String getResult() throws Exception{
try{
String result = sample.getName();
//some code
}catch(){
//here i need to handle exceptions
}
return result;
}
My requirement is:
sample.getName() can throw CustomException and it can also throw RunTimeExceptions.
In the catch block, I need to catch the exception. If the exception that is caught is RunTimeException then I need to check if the RunTimeException is an instance of SomeOtherRunTimeException. If so, I should throw null instead.
If RunTimeException is not an instance of SomeOtherRunTimeException then I simply need to rethrow the same run time exception.
If the caught exception is a CustomException or any other Checked Exception, then I need to rethrow the same. How can I do that?

You can do like this :
catch(RuntimeException r)
{
if(r instanceof SomeRunTimeException)
throw null;
else throw r;
}
catch(Exception e)
{
throw e;
}
Note: Exception catches all the exceptions. That's why it is placed at the bottom.

You can simply do:
public String getResult() throws Exception {
String result = sample.getName(); // move this out of the try catch
try {
// some code
} catch (SomeOtherRunTimeException e) {
return null;
}
return result;
}
All other checked and unchecked exceptions will be propagated. There is no need to catch and rethrow.

Related

How to handle a runtime error with throws

In the following code snippet, there are cases where the processes cannot handle NullPointerException and IllegalStateException. Namely in the case where I have the input values val=-4 or val=-2.
I read that adding throws after methods' signatures would help. But the code still aborts if I pass the mentioned values over.
public class Test extends Throwable{
public static void processA(int val ) throws NullPointerException, IllegalStateException{
try{
System.out.println("1");
processB(val);
}catch(ArithmeticException e){
System.out.println("2");
}
System.out.println("3");
}
public static void processB(int val) throws NullPointerException, IllegalStateException{
try{
System.out.println("4");
processC(val);
}catch(NullPointerException e){
System.out.println("5");
processC(val+4);
}finally{
System.out.println("6");
}
System.out.println("7");
}
public static void processC(int val)throws NullPointerException, IllegalStateException, ArithmeticException{
System.out.println("8");
if(val<1) throw new NullPointerException();
if(val==1) throw new ArithmeticException();
if(val>1) throw new IllegalStateException();
System.out.println("9");
}
public static void main(String[] args) throws Exception {
processA(1); //processA(-2) or processA(-4)
}
}
It breaks because you are not handling the scenario when a NullPointerException or IllegalStateException is thrown to processA(...). You only handle an ArithmeticException.
Add the following to your code, thereby if any of the three exceptions are thrown, it is handled by method processA.
public static void processA(int val) throws NullPointerException, IllegalStateException {
try {
System.out.println("1");
processB(val);
} catch (ArithmeticException e) {
System.out.println("11");
} catch (NullPointerException e) {
System.out.println("12");
} catch (IllegalStateException e) {
System.out.println("13");
}
System.out.println("3");
}
If you want the caller to handle them then you need to do the same from the caller method. For eg :
public static void main(String[] args) {
try {
processA(12);
} catch (ArithmeticException | NullPointerException | IllegalStateException e) {
// do something here
}
}
To answer your question in the comments: "But why should I use it?"
This will indicate that the caller will need to handle the exception thrown by that method. Now the caller can handle it via a try-catch block or it can re-throw the exception to its caller. The compiler would also give you an error saying that the exception should be handled but this would happen only for checked exceptions. The ones you are throwing are unchecked exceptions. Which means in your case you can pretty much ignore them from the method declaration.
I would suggest you also consider using Thread.UncaughtExceptionHandler in order to make sure you properly handle exceptions which were not properly caught.
Missing out on exception handling is a very common occurrence and can be easily avoided using this API.
References:
How to catch an exception from a thread
Oracle official API
UncaughtExceptionHandler as a best practice

Compiler does not complain that I catch an exception that can never be thrown

I am reading a More precise rethrows in java 7 http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html which says
In detail, in Java SE 7 and later, when you declare one or more
exception types in a catch clause, and rethrow the exception handled
by this catch block, the compiler verifies that the type of the
rethrown exception meets the following conditions:
The try block is able to throw it.
There are no other preceding catch blocks that can handle it.
It is a subtype or supertype of one of the catch clause's exception parameters.
so i wrote a program to test it .
public class MorePreciseRethrow {
public static void main(String args[]){
try {
foo("First");
} catch (FirstException e) {
e.printStackTrace();
} catch (SecondException e) {
e.printStackTrace();
}
}
private static void foo(String exceptionName) throws FirstException, SecondException{
try{
if(StringUtils.equals("First",exceptionName)){
throw new FirstException();
}
}catch(Exception e){
throw e;
}
}
}
class FirstException extends Exception{
}
class SecondException extends Exception{
}
but this doesn't generate even a compiler warning with jdk7.
Now my try block is never able to throw SecondException, but my compiler didn't check it . Is the mentioned line in doc is wrong or am i doing some mistake ?
The compiler only checks if the method header
private static void foo(String exceptionName) throws FirstException, SecondException
declairs thr exception.
You can have multiple implementations of methods so one implementation can throw the exeption and one not. but both must bedeclaired.
In java, there is no requirement that the code in a method that declares that it throws an exception actually be able to throw it.
This makes sense, because the method may be implementing an interface, but the implementation happens to not throw it, or it could allow for future expansion to an implementation/subclass that does throw it.
In order to get the compilation error that documentation is talking about, you need to use a multiple catch. Something like,
private static void foo(String exceptionName) throws FirstException,
SecondException {
try {
throw new FirstException();
} catch (FirstException | SecondException e) {
throw e;
}
}
Creates an UnreachableCodeBlock for SecondException in Java 7+.

Factory pattern to create Exceptions dynamically

I have created Exception xml and dynamically create and throw exception.
<exception-mappings>
<exception-mapping key="exceptionkey1">
<class-name>com.package.CheckedException</class-name>
<message>Checked Exception Message</message>
</exception-mapping>
<exception-mapping key="exceptionkey2">
<class-name>com.package.UnCheckedException</class-name>
<message>UnChecked Exception Message</message>
</exception-mapping>
I create object of exception dynamically using reflection depending on the exception key.
public static void throwException(final String key) throws CheckedException, UncheckedException {
ExceptionMapping exceptionMapping = exceptionMappings.getExceptionMappings().get(key);
if (exceptionMapping != null) {
try {
Class exceptionClass = Class.forName(exceptionMapping.getClassName());
try {
throw ()exceptionClass.newInstance(); // line X
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I want to know which class to typecast at line X so that I do not need to use If/else. Reason behind I do not want to use if else is, it may be possible that in future, there may be new classes added and I do not want to change this code every time new exception is added.
My base logic is my service layer will throw either CheckedException or UncheckedException. If CheckedException is thrown, it will be handled by my web layer. Also I can not throw Super parent class Exception or Throwable as my web layer only catch CheckedException. If UncheckedException is thrown, it will display exception page.
Please help me as I am not able to proceed further.
EDIT: Any other solution is also accepted.
Well, in the name of science, here's how you can do it. Would I recommend doing this? By no means. Would I ever do anything remotely like this myself? Probably not.
public class ExceptionFactory {
public static void throwException(String className)
throws CheckedException, UncheckedException {
Class<?> exceptionClass;
try {
exceptionClass = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
try {
if (CheckedException.class.isAssignableFrom(exceptionClass)) {
throw exceptionClass.asSubclass(CheckedException.class)
.newInstance();
} else if (UncheckedException.class
.isAssignableFrom(exceptionClass)) {
throw exceptionClass.asSubclass(UncheckedException.class)
.newInstance();
} else {
throw new IllegalArgumentException(
"Not a valid exception type: "
+ exceptionClass.getName());
}
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void main(String... args) {
try {
throwException("CheckedException");
} catch (CheckedException e) {
System.out.println(e);
} catch (UncheckedException e) {
System.out.println(e);
}
}
}
class CheckedException extends Exception {
}
class UncheckedException extends Exception {
}
I don't see the point of this factory. Even if you get it to work (which you can by having all the exceptions thrown by it being sub-classes of a single ancestor class), its usage would be something like this :
....
if (somethingInWrong) {
ExceptionFactory.throwException("SomeKey");
}
....
For each key you'd still have to create an exception class to be mapped to it. Lets say SomeKeyException is the exception mapped to "SomeKey".
In that case, it's much more type safe to simply write :
....
if (somethingInWrong) {
throw new SomeKeyException();
}
....
This way the compiler checks that you are creating an exception class that it actually knows. If you use your Factory, you might use some String that is not a valid key, and the compiler won't be able to do anything about it. Only in runtime your Factory will fail to find an exception mapped to the invalid key.
There's no need to use reflection (as I commented above you shouldn't use reflection unless you really have to...).
You can implement the exceptions class to be something like this:
class MyExceptions {
static void myExceptionsThrower(String key) throws Exception {
if("illegalstate".equals(key)) {
throw new IllegalStateException("that's my IllegalStateException bro!");
}
else if("illegalaccess".equals(key)) {
throw new IllegalAccessException("that's my IllegalAccessException bro!");
}
// etc...
}
}
and use it with:
MyExceptions.myExceptionsThrower(key);
A few tweaks:
public static void throwException(final String key) throws Throwable {
ExceptionMapping exceptionMapping =
exceptionMappings.getExceptionMappings().get(key);
if (exceptionMapping != null) {
try {
Class<Throwable> exceptionClass =
(Class<Throwable>)Class.forName(exceptionMapping.getClassName());
try {
throw exceptionClass.cast( exceptionClass.newInstance() ); // line X
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Here's my entry into this derby. :-)
The other answers have commented on whether this is a reasonable design. I'll set these issues aside for the purpose of this answer.
A couple of my pet peeves are unnecessary warnings (even if suppressed), and exceptions that don't report what actually went wrong. In particular merely printing out a stack trace is usually insufficient. Yes, this is just test code, but when dealing with code like this -- even code that's designed to throw an exception -- one really ought to think about how to deal with errors. In this case I've chosen to represent these kinds of errors as instances of InternalError since the configuration or whatever can be wrong in a variety of ways. Specifically: if the class can't be found, if it is found but isn't a subtype of CheckedException or UncheckedException (or even an ordinary class), or if doesn't have a no-arg constructor or if it's inaccessible.
Another issue with some of the proposed solutions is that if the exception class name is "java.lang.InstantiationException" (or one of the other internally-caught exceptions) an instance of this exception type might be constructed, thrown, and then caught internally, resulting in a stack trace but not actually throwing the requested exception. I've avoided that by linearizing the logic instead of nesting try-catch blocks.
Finally, I extracted the exception-creating code into a separate method so that it can be used for both the checked and unchecked cases. This can be simplified considerably if you rearrange the exception hierarchy to allow only a single root exception (I recommend unchecked) and have exception subtypes that are handled at the web layer or are thrown out to the caller.
static void throwException(final String exClassName) throws CheckedException, UncheckedException {
Class<?> clazz;
try {
clazz = Class.forName(exClassName);
} catch (ClassNotFoundException cnfe) {
throw new InternalError(exClassName, cnfe);
}
if (CheckedException.class.isAssignableFrom(clazz)) {
throw newException(clazz.asSubclass(CheckedException.class));
} else if (UncheckedException.class.isAssignableFrom(clazz)) {
throw newException(clazz.asSubclass(UncheckedException.class));
} else {
throw new InternalError(exClassName + " is not a valid exception");
}
}
static <X extends Throwable> X newException(Class<X> clazz) {
X x;
try {
x = clazz.newInstance();
} catch (InstantiationException|IllegalAccessException e) {
throw new InternalError("creating instance of " + clazz, e);
}
return x;
}
This could be helpful to create a custom precondition exception to avoid multiple if conditions.
Creates a precondition exception while checking for null pointer.
class Preconditions {
/**
* <p>
* Checks the value to be null and if null throws a new Exception with the message given.
* Used to reduce checking if conditions for complexity.
* </p>
* #param val - val to check null
* #param exceptionClass - exception class to be thrown
* #param args - message to be called for throwing exception
* #throws Throwable - Common Throwable Exception.
*/
public static void checkNotNull(final Object val, final Class<?> exceptionClass, final Object ...args) throws Throwable {
Class<?>[] argTypes = new Class<?>[args.length];
Arrays.stream(args).map(WithIndex.indexed()).forEach(arg ->argTypes[arg.index()] = arg.value().getClass());
if (null == val) throw (Throwable) exceptionClass.getConstructor(argTypes).newInstance(args);
}
}
Then you can use it in code with:
PreConditionUtil.checkNotNull(objectToCheck, CustomException.class, ErrorCode, "your error message", ...);

Java Error: Unreported exception?

I've got the following method:
public T peek() throws StackEmptyException {
Node<T> tracker = head;
while(tracker.getNext() != null) {
tracker = tracker.getNext();
}
return tracker.getItem();
}
The problem is that when I try to do something like
int firstOne = stack.peek();
I get an unreported exception StackEmptyException and I have no idea what I'm doing wrong at this point. The StackEmptyException has been made in a separate class. Am I suppose to have this class extend that new exception class I made? So confused. Thoughts guys?
Since StackEmptyException is an checked exception (which you shouldn't do in first place), you should handle that exception when invoking the peek() method. The rule is, either you should handle the exception or declare it to be thrown.
However, I would take a step back and change StackEmptyException to an Unchecked Exception. Then you wouldn't need to handle it or declare it as thrown.
Checked exceptions (ie, a class which extends Exception but not RuntimeException or Error) thrown by a method should be handled by this method's caller, recursively so.
Here you have .peek() which throws, say, exception class E (bad name, but this is for illustration). You must do one of the following in a foo() method which calls .peek():
catch it, or
throw it again.
That is, either:
// catch
void foo()
{
try {
peek();
} catch (E e) {
// something
}
}
or:
// throw
void foo() throws E
{
peek();
}
You could even rethrow it:
// catch then rethrow
void foo() throws E
{
try {
peek();
} catch (E e) {
// something, then
throw e;
}
}

How does the correct rethrow code look like for this example

Yesterday I red this article about the new Exception Handling in Java 7.
In the article they show an example (No 4) which is not working in Java 6. I just copied it.
public class ExampleExceptionRethrowInvalid {
public static void demoRethrow()throws IOException {
try {
// forcing an IOException here as an example,
// normally some code could trigger this.
throw new IOException("Error");
}
catch(Exception exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
public static void main( String[] args )
{
try {
demoRethrow();
}
catch(IOException exception) {
System.err.println(exception.getMessage());
}
}
}
Like in the article descriped it won't compile, because of the type missmatch -throws IOException- and -throw exception-. In Java 7 it will. So my question is.
How do I proper implement this kind of rethrowing of an exception in Java 6? I don't like the suggested implementation example no five. I know it is a matter of taste and problem you try to handle if unchecked exceptions or not. So what can I do to get the -throws IOException- and keep the stack trace? Should I only change the catch to IOException and risk not catching all?
I'm curious about your answers.
Simply catch IOException, like so:
public static void demoRethrow()throws IOException {
try {
// forcing an IOException here as an example,
// normally some code could trigger this.
throw new IOException("Error");
}
catch(IOException exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
If the code inside the try block can throw a checked exception other than IOException, the compiler will flag this up as an error, so you're not "risk[ing] not catching all".
If you're also interested in unchecked exceptions, you could also catch and re-throw RuntimeException (you won't need to declare it in the throws clause).
Catch IOException and everything else separately:
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(IOException exception) {
throw exception;
}
catch(Exception exception) {
throw new IOException(exception);
}
catch(Exception ex) catches both checked and unchecked (RuntimeException) exceptions.
So to make it functionaly equivalent,
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(IOException exception) {
throw exception;
}
catch(RuntimeException exception) {
throw new IOException(exception);
}
suffice, and compiler will detect other checked exceptions (good for thinking again about whether they should realy get this far, or should have bean delt with before)
A hacky way to throw to catch a generic exception and rethrow without the compiler checking the exception is to use stop.
public static void demoRethrow() throws IOException {
try {
throw new IOException("Error");
} catch(Throwable t) {
// handle exception
// rethrow the exception without compiler checks.
Thread.currentThread().stop(t);
}
}

Categories