Cleonjoys
Cleonjoys

Reputation: 504

Facing Issue with Custom Exception in Java

I am continuously getting the error: TestException.java:8: error: unreported exception Throwable; must be caught or declared to be thrown

throw new ParentException().initCause(new ChildException().initCause(new SQLException()));

Any idea, i know some trivial thing is missing which i am not getting readily to my mind, thanks, don't take source for the face value, i am trying to just refresh my understanding.

    import java.sql.SQLException;

    public class TestException{

    public static void main(String[] args) {

    try{
            throw new ParentException().initCause(new ChildException().initCause(new SQLException()));
    }
    catch(ParentException | ChildException | SQLException e){
            e.printStackTrace();
            try{
                    Thread.sleep(10*1000);
            }
            catch(Exception et){
                    ;
            }
    }

    }
 }

  class ParentException extends Exception{

    public ParentException(){
            super("Parent Exception is called");
    }

}

 class ChildException extends Exception{

    public ChildException(){
            super("Child Exception is called");
    }

}

Upvotes: 0

Views: 238

Answers (4)

Codi
Codi

Reputation: 541

The initCause(Throwable cause) function returns an object of Throwable : public synchronized Throwable initCause(Throwable cause) and so when you do throw new ParentException().initCause(new ChildException().initCause(new SQLException()));, you are basically doing throw ( new ParentException().initCause(new ChildException().initCause(new SQLException())) ) ;, so you are doing throw <ThrowableObject>, hence you must catch an Exception of Throwable.

try {
    throw new ParentException().initCause(new ChildException().initCause(new SQLException()));
} catch (Throwable e) {
     e.printStackTrace();
     try {
         Thread.sleep(10*1000);
     } catch(Exception ex) {}

You can fix this in multiple ways, the 2 best ways I feel are by either overloading the constructors in both ParentException and ChildException with

public ParentException(Throwable cause) { 
    super("Parent Exception is called", cause);
}

and similar version for ChildException and using

throw new ParentException(new ChildException(new SQLException()));

instead of initcause(), or, by doing the following instead

try {
    ParentException p = new ParentException();
    p.initCause(new ChildException().initCause(new SQLException()));
    throw p;
} catch (ParentException e) {
    e.printStackTrace();
    try{
        Thread.sleep(10*1000);
    } catch(Exception ex) {}

Note: you need to catch only ParentException and no other Exception as it is the only Exception which may be thrown inside the body of try. Attempting to catch other Exceptions (which are not superclasses of ParentException will give the error that you are trying to catch an Exception that is never thrown.

Upvotes: 0

Nishant Lakhara
Nishant Lakhara

Reputation: 2445

Simply Because initCause returns a Throwable instance :

public synchronized Throwable initCause(Throwable cause)

While catch clause is not able to catch any Throwable reference. You can add Throwable along with other exceptions.

try {
            throw new ParentException().initCause(new ChildException().initCause(new SQLException()));
        } catch (ParentException | ChildException | SQLException e) {
            e.printStackTrace();
            try {
                Thread.sleep(10 * 1000);
            } catch (Exception et) {
                ;
            }
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

OR Just catch Throwable , if you want to catch all throwables including mentioned three exceptions and all other error , exceptions that extends Throwable

try {
            throw new ParentException().initCause(new ChildException().initCause(new SQLException()));

        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

Upvotes: 1

Rama Krishna
Rama Krishna

Reputation: 120

initCause() will throw Throwable object, so you should catch that exception

    catch (Throwable e)
    {            
        e.printStackTrace();
    }

Upvotes: 1

xp500
xp500

Reputation: 1426

initCause returns a Throwable.

That means you're actually throwing a Throwable and not a ParentException so the compiler is complaining that you are throwing a Throwable but are not catching it.

You can fix this by changing ParentException and ChildException so that they not only receive the error message but also receive the cause. You can then call the Exception constructor that receives a message and a cause

Upvotes: 1

Related Questions