Throwing exception from lambda
Solution 1
My approach would be to sneakily throw it from the lambda, but take care to have the send
method declare it in its throws
clause. Using the Exceptional
class I posted here:
public Server send(String message) throws IOException {
sessions.parallelStream()
.map(Session::getBasicRemote)
.forEach(basic -> Exceptional.from(() -> basic.sendText(message)).get());
return this;
}
This way you're effectively making the compiler "look away" for just a bit, disabling its exception checking at one spot in your code, but by declaring the exception on your send
method, you restore the regular behavior for all its callers.
Solution 2
I wrote an extension to the Stream API which allows for checked exceptions to be thrown.
public Server send(String message) throws IOException {
ThrowingStream.of(sessions, IOException.class)
.parallelStream()
.map(Session::getBasicRemote)
.forEach(basic -> basic.sendText(message));
return this;
}
Solution 3
The problem is indeed that all @FunctionalInterface
s used in lambdas do not allow exceptions to be thrown, save for unchecked exceptions.
One solution is using a package of mine; with it, your code can read:
sessions.parallelStream()
.map(Session::getBasicRemote)
.forEach(Throwing.consumer(basic -> basic.sendText(message)));
return this;
vach
Updated on June 23, 2022Comments
-
vach almost 2 years
Given this java 8 code
public Server send(String message) { sessions.parallelStream() .map(Session::getBasicRemote) .forEach(basic -> { try { basic.sendText(message); } catch (IOException e) { e.printStackTrace(); } }); return this; }
how do we properly make this
IOException
be delegated up the stack of the method call? (in nutshell how to make this method throw thisIOException
?)Lambdas in java does not look very friendly to error handling...
-
T.J. Crowder over 8 yearsHow does that let
send
throw the exception? -
T.J. Crowder over 8 years@MarkoTopolnik: I understand that. But a lot more work is required to then make
send
throw theIOException
. If I'm not mistaken, you basically have to catch theThrownByLambdaException
, and then have a series ofinstanceof
to figure out what the actual exception was so you can rethrow it. Maybe not that bad for one or two exceptions, but still pretty verbose. -
T.J. Crowder over 8 yearsOh now I like that. That is indeed very sneaky.
-
Marko Topolnik over 8 years@T.J.Crowder To stay fair to our colleague fge (and as you discovered in our chat),
throwing-lambdas
does support the sneaky throwing idiom. -
T.J. Crowder over 8 years@MarkoTopolnik: Although as far as I can tell, the above doesn't actually use it, nor was it explained (e.g., that if it does use a sneaky throw, the
throws
decl. onsend
is essential and the compiler won't force you to add it). -
vach over 8 yearsthanks, now this is really nice interface :) will definitely check out your source code