[concurrency-interest] Layered exception handling with CompletableFuture

√iktor Ҡlang viktor.klang at gmail.com
Wed Aug 27 06:57:59 EDT 2014


On Wed, Aug 27, 2014 at 12:14 PM, Mark Thornton <mthornton at optrak.com>
wrote:

> Except that you then have trouble catching a checked exception that
> appears not to be thrown. You have to wrap the code in a method which does
> declare the checked exception(s) you want to catch.


I tend to catch Exception (one shouldn't catch Throwable/Error anyway) and
if you want to escalate you rethrow sneakily).

  public static RuntimeException sneaky(Throwable t) {
        if ( t == null ) throw new NullPointerException("t");
        AbstractActorCell.<RuntimeException>sneakyThrow0(t);
        return null;
    }

    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void sneakyThrow0(Throwable t)
throws T {
        throw (T)t;
    }

    public static java.lang.String foo() {
        try {
            throw new SQLException("foo");
        } catch(SQLException e) { // Get rid of checked exceptions as you
need to deal with RuntimeExceptions anyway
            throw sneaky(e);
        }
    }

    public static int bar() {
        try {
            foo();
        } catch(Exception e) {
            if (e instanceof SQLException) {
              //deal with SQLExceptions
            } else
                throw sneaky(e);
        }
        return 2;
    }


>
> Mark Thornton
>
>
> On Wednesday, 27 August 2014, √iktor Ҡlang <viktor.klang at gmail.com> wrote:
>
>> I -always- use "sneakyThrows" to turn checked exceptions into unchecked
>> ones—there's 0 value in checked exceptions. (Checked exceptions is a Java
>> language feature, not a JVM feature)
>>
>> http://www.jayway.com/2010/01/29/sneaky-throw/
>>
>> The only rough edge I've found is with dynamic Proxies, which encode this
>> language feature into a runtime feature:
>> http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/UndeclaredThrowableException.html
>>
>>
>> On Wed, Aug 27, 2014 at 10:39 AM, Millies, Sebastian <
>> Sebastian.Millies at softwareag.com> wrote:
>>
>>>  Hi,
>>>
>>>
>>>
>>> thank you for the helpful response.
>>>
>>>
>>>
>>> It made me remember dimly some discussion of exception transparency on
>>> lambda-dev, and how it finally wasn’t possible to make it work. I do not
>>> believe this will ever be solved on the language level, and I regret that.
>>> In the same vein CompletableFuture.suppyAsync() does not accept a Callable,
>>> only a Supplier. In my situation there’s a bunch of pre-existing, exception
>>> throwing application methods (not to mention the Java library methods) that
>>> I now have a new requirement to combine asynchronously. So I find myself
>>> wrapping all the Callables, and tunneling the exceptions with
>>> RuntimeException, as Doug Lea recommends.
>>>
>>>
>>>
>>> I have looked at your suggestion, and I’m sorry to say I do not see how
>>> it would help, unless I rewrite everything from scratch or use bayou (would
>>> need something like your Async interface).
>>>
>>> And it also does not seem to address the one-stop exception-handling
>>> concern, because guess I would somehow need to call
>>> CompletableFuture#handle() and that can’t throw. Even in bayou, from a
>>> cursory look at Async.java, it seems that catch_() doesn’t rethrow the
>>> exception if it is not of the appropriate class.
>>>
>>>
>>>
>>> Best,
>>>
>>> Sebastian
>>>
>>>
>>>
>>> *From:* Zhong Yu [mailto:zhong.j.yu at gmail.com]
>>> *Sent:* Wednesday, August 27, 2014 2:02 AM
>>> *To:* Millies, Sebastian
>>> *Cc:* concurrency-interest at cs.oswego.edu
>>> *Subject:* Re: [concurrency-interest] Layered exception handling with
>>> CompletableFuture
>>>
>>>
>>>
>>> [OP snipped]
>>>
>>> Apparently, CompletableFuture does not  take too kindly to checked
>>> exceptions [1].
>>>
>>> A lot of people even consider checked exceptions a design mistake on the
>>> language level. Nevertheless, most Java programmers and APIs do use checked
>>> exceptions, for returning alternative results, and for flow controls.
>>>
>>> A workaround is to create your own helper method like
>>>
>>>     static <T,X> CF<T> catch_(CF<T> cf, Class<X> exceptionType,
>>> FuncE<X,T> exceptionHandler) { ... }
>>>
>>> where FuncE is similar to Function, except the apply() method throws
>>> `Exception`
>>>
>>>
>>>
>>> Then you can use it like
>>>
>>>     catch_( future, SomeException.class, ex->someValue )
>>>
>>>     catch_( future, SomeExcpetion.class, ex->throw new
>>> AnotherException() )
>>>
>>> That is what we did in bayou Async API [2]. The problem you posted early
>>> can be solved in bayou as
>>>
>>>     Async.execute(...)
>>>               .timeout(...)
>>>               .catch_(TimeoutException.class, ex->defaultValue);
>>>
>>>
>>> [1]
>>> http://cs.oswego.edu/pipermail/concurrency-interest/2012-December/010486.html
>>> [2]
>>> http://bayou.io/release/0.9/docs/async/Async_Programming.html#Sequential_Actions
>>>
>>>
>>>   Zhong Yu
>>>
>>> bayou.io
>>>
>>>    Software AG – Sitz/Registered office: Uhlandstraße 12, 64297
>>> Darmstadt, Germany – Registergericht/Commercial register: Darmstadt HRB
>>> 1562 - Vorstand/Management Board: Karl-Heinz Streibich
>>> (Vorsitzender/Chairman), Dr. Wolfram Jost, Arnd Zinnhardt; -
>>> Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas
>>> Bereczky - *http://www.softwareag.com* <http://www.softwareag.com>
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>>>
>>
>>
>> --
>> Cheers,
>>>>
>


-- 
Cheers,
√
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140827/9c92f008/attachment.html>


More information about the Concurrency-interest mailing list