HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavaMinor

Catch all checked exceptions and turn into unchecked exception

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
turnexceptionsexceptionallintocatchandcheckedunchecked

Problem

I am currently trying to learn Lambdas and following the book Java SE8 for the really Impatient and just finished Chapter 1 of it. This is the question, I am trying to get done with:


Didn’t you always hate it that you had to deal with checked exceptions
in a Runnable? Write a method uncheck that catches all checked
exceptions and turns them into unchecked exceptions. For example,

new Thread(uncheck( () -> { System.out.println("Zzz"); Thread.sleep(1000); })).start(); // Look, no catch (InterruptedException)!




Hint: Define an
interface RunnableEx whose run method may throw any exceptions. Then
implement public static Runnable uncheck(RunnableEx runner). Use a
lambda expression inside the uncheck function. Why can’t you just use
Callable instead of RunnableEx?

This is my solution:

@FunctionalInterface
public interface RunnableEx extends Runnable {
    @Override
    default void run () {
        try {
            doRun();
        } catch (Error | RuntimeException e) {
            throw e;
        } catch (Throwable throwable) {
            throw new IndexOutOfBoundsException("IOBE");
        }
    }

    void doRun ()
        throws Throwable;
}


and

public class Question6 {
    public static void main (String... args) {
        uncheck(() -> {
            System.out.println("Question6");
        });
    }

    public static Runnable uncheck (final RunnableEx runner) {
        final RunnableEx runnable = () -> {
            try {
                runner.doRun();
            } catch (Error | RuntimeException e) {
                throw e;
            } catch (Throwable ignored) {
                runner.doRun();
            }
        };

        return runnable;
    }

    // We can not use Callable because it throws Checked Exception.
}


I request two things:

  • How can this be improved, if it can be?



  • As per my understanding, this implementation seems to be correct, but is it really?

Solution

default void run () {


There should be no blank after a method name (neither in a declaration not in a call). There are only blanks after if and while to distinguish them visually from method calls.

try {
        doRun();
    } catch (Error | RuntimeException e) {
        throw e;
    } catch (Throwable throwable) {
        throw new IndexOutOfBoundsException("IOBE");
    }


Really IndexOutOfBoundsException??? What index, what bounds? It should be

try {
        doRun();
    } catch (Error | RuntimeException e) {
        throw e;
    } catch (Throwable e) {
        throw new RuntimeException(e);
    }


It's called exception wrapping. You can't throw e, so you wrap it into a RuntimeException and it can be obtained via getCause. Printing the stack does it, so you lose no information.

final RunnableEx runnable = () -> {
        try {
            runner.doRun();
        } catch (Error | RuntimeException e) {
            throw e;
        } catch (Throwable ignored) {
            runner.doRun();
        }
    };


The line runner.doRun() makes no sense to me. It failed, so you do it again. Why?

Moreover, it may throw a Throwable.

Moreover, you're repeating what you did above.

You've been already given a workable example in the question:

new Thread(uncheck( () -> { System.out.println("Zzz"); Thread.sleep(1000); })).start(); // Look, no catch (InterruptedException)!

Code Snippets

default void run () {
try {
        doRun();
    } catch (Error | RuntimeException e) {
        throw e;
    } catch (Throwable throwable) {
        throw new IndexOutOfBoundsException("IOBE");
    }
try {
        doRun();
    } catch (Error | RuntimeException e) {
        throw e;
    } catch (Throwable e) {
        throw new RuntimeException(e);
    }
final RunnableEx runnable = () -> {
        try {
            runner.doRun();
        } catch (Error | RuntimeException e) {
            throw e;
        } catch (Throwable ignored) {
            runner.doRun();
        }
    };
new Thread(uncheck( () -> { System.out.println("Zzz"); Thread.sleep(1000); })).start(); // Look, no catch (InterruptedException)!

Context

StackExchange Code Review Q#97045, answer score: 6

Revisions (0)

No revisions yet.