From 9b5e6412464b5e0c8801a6e3150fa0732641173f Mon Sep 17 00:00:00 2001 From: "He-Pin(kerr)" Date: Fri, 19 Sep 2025 22:44:53 +0800 Subject: [PATCH] feat: Add sneakyThrow for Java (#2218) --- .../java/org/apache/pekko/japi/ThrowablesTest.java | 9 +++++++++ .../main/scala/org/apache/pekko/japi/Throwables.scala | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/actor-tests/src/test/java/org/apache/pekko/japi/ThrowablesTest.java b/actor-tests/src/test/java/org/apache/pekko/japi/ThrowablesTest.java index 7c7f9ac504..ac7759c6d1 100644 --- a/actor-tests/src/test/java/org/apache/pekko/japi/ThrowablesTest.java +++ b/actor-tests/src/test/java/org/apache/pekko/japi/ThrowablesTest.java @@ -29,4 +29,13 @@ public class ThrowablesTest { Assert.assertTrue(Throwables.isFatal(new InterruptedException("fatal"))); Assert.assertTrue(Throwables.isFatal(new LinkageError("fatal"))); } + + private void doSneakyThrow() { + Throwables.sneakyThrow(new Exception("sneaky")); + } + + @Test + public void testSneakyThrow() { + Assert.assertThrows("sneaky", Exception.class, this::doSneakyThrow); + } } diff --git a/actor/src/main/scala/org/apache/pekko/japi/Throwables.scala b/actor/src/main/scala/org/apache/pekko/japi/Throwables.scala index 184b143663..0cab67fe1c 100644 --- a/actor/src/main/scala/org/apache/pekko/japi/Throwables.scala +++ b/actor/src/main/scala/org/apache/pekko/japi/Throwables.scala @@ -49,4 +49,15 @@ object Throwables { * or false if it is to be considered non-fatal */ def isFatal(throwable: Throwable): Boolean = !isNonFatal(throwable) + + /** + * Throws the given `Throwable`, without requiring the caller to declare it in a `throws` clause. + * @param t the `Throwable` to throw + * @throws T the type of the `Throwable` to throw + * @return never returns normally, but has return type `R` to allow usage in expressions + * @since 2.0.0 + */ + def sneakyThrow[T <: Throwable, R](t: Throwable): R = { + throw t.asInstanceOf[T] + } }