DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Unreachable Catch Block - A Most Unobvious Bug

Roger Hughes user avatar by
Roger Hughes
·
Feb. 10, 12 · Interview
Like (0)
Save
Tweet
Share
14.75K Views

Join the DZone community and get the full member experience.

Join For Free

Earlier today I was working on some HTTP comms code adding a few changes, which are of no consequence here. One of the things that the code did was to read data from a server and, if the read failed, then it re-newed the connection and retried the read. The code ran something like this:

    HttpClient httpclient = // this is org.apache.http.client.HttpClient
    HttpResponse response;
    try {
      response = httpclient.execute(httpget, localContext);
    } catch (HttpResponseException e) {
      refreshHttpClient(httpclient);
      response = httpclient.execute(httpget, localContext);
    }

The idea is that the execute() method is supposed to throw an HttpResponseException in order to trigger a re-connection, except that the execute() method, according to the JavaDoc will NEVER throw that exception. You’d therefore expect that the compiler to give you an “Unreachable catch block” error, EXCEPT THAT IN THIS CASE IT DOESN’T. Why?

The answer is that the execute() method throws an IOException; an exception that is a superclass of the catch block exception HttpResponseException. The catch block will ignore the superclass exception as it’s only looking for the subclass exception.

To prove it, take a look at the simple example below.

public class CatchingExceptionsExample {

  public static class SampleClass {

    /**
     * Example method - throws IOException
     *
     * @throws IOException
     */
    public void method() throws IOException {

      throw new IOException("Whoops");
    }
  }

  public static class MyException extends IOException {

    private static final long serialVersionUID = 1L;

    public MyException(String msg) {
      super(msg);
    }
  }

  public static void main(String[] args) throws IOException {

    System.out.println("Running");
    try {
      SampleClass sample = new SampleClass();
      sample.method();

    } catch (MyException e) {
      System.out.println("Exception Caught");
    } finally {
      System.out.println("Ending");
    }
  }

}

Here I have an exception MyException that extends IOException and a class SampleClass that implements a sample method: method(), which throws an IOException.

The output from this code is:

Running
Ending

...demonstrating that the catch block is unreachable.

Now, my first thought was to categorise this as a bug in Java, after all you want to know when there's an unreachable catch block and the compiler / eclipse usually tells you about it with this message...


...but it isn't a bug in Java it's there intentionally and it's just one of those little Gotchas that leaps up and bites you. The reason it it intentional can be explained by looking at the following chunk of code...

public class CatchingExceptionsExample2 {

  public static class SampleClass {

    public void method() throws IOException {

      AnotherSampleClass anotherSampleClass = new AnotherSampleClass();
      anotherSampleClass.anotherMethod();
    }
  }

  public static class AnotherSampleClass {

    public void anotherMethod() throws MyException {

      throw new MyException("My Exception");
    }
  }

  public static class MyException extends IOException {

    private static final long serialVersionUID = 1L;

    public MyException(String msg) {
      super(msg);
    }
  }

  public static void main(String[] args) throws IOException {

    System.out.println("Running");
    try {
      SampleClass sample = new SampleClass();
      sample.method();

    } catch (MyException e) {
      System.out.println("Exception Caught");
    } finally {
      System.out.println("Ending");
    }
  }
}

In this code the method() method creates AnotherSampleClass and calls anotherMethod(). anotherMethod() does throw MyException, which because it's a subclass of IOException gets passed up the call-stack without any problems and is caught in the main() method. This time the output is:

Running
Exception Caught
Ending

Finally, I guess the point is that the compiler can't raise this gotcha as a problem as it'll never know if a method called in a try/catch block that then calls another method in an class or another class will throw an exception that is a subclass of the originally thrown exception... phew.

 

From http://www.captaindebug.com/2012/02/unreachable-catch-block-most-unobvious.html

Blocks

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • GitLab vs Jenkins: Which Is the Best CI/CD Tool?
  • Rust vs Go: Which Is Better?
  • [DZone Survey] Share Your Expertise and Take our 2023 Web, Mobile, and Low-Code Apps Survey
  • How Elasticsearch Works

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: