projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.93k stars 2.4k forks source link

[FEATURE] @SneakyReThrow #3771

Open cristcost opened 3 weeks ago

cristcost commented 3 weeks ago

Describe the feature Background: I don't like SneakyThrow because it violates the Java contracts, but I'd love a boilerplate saving functionality to reduce exception handling code.

This feature request is to ask for a @SneakyReThrow annotation, which doesn't throw the checked annotation directly, but instead rethrows a different exception (by default, a RuntimeException) with the original annotation as cause and additionally supports a message.

Example of how the documentation would look like:

WITH LOMBOK

public class SneakyReThrowsExample implements Runnable {

  // similar to @SneakyThrows(UnsupportedEncodingException.class)
  @SneakyReThrows(
      catching = UnsupportedEncodingException.class,
      rethrowing = RuntimeException.class,
      message = "Error while parsing bytes to string")
  public String utf8ToString(byte[] bytes) {
    return new String(bytes, "UTF-8");
  }

  // similar to @SneakyThrows({IOException.class, ClassNotFoundException.class})
  @SneakyReThrows(
      catching = {IOException.class, ClassNotFoundException.class},
      rethrowing = RuntimeException.class,
      message = "Error while loading class from configuration")
  public Class<?> getMyClass() {
    String className = Files.readString(Path.of("classname.config"));
    return Class.forName(className);
  }

  // similar to @SneakyThrows
  @SneakyReThrows
  public void run() {
    throw new Throwable();
  }
}

VANILLA JAVA

public class SneakyReThrowsExample implements Runnable {

  public String utf8ToString(byte[] bytes) {
    try {
      return new String(bytes, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("Error while parsing bytes to string", e);
    }
  }
  public Class<?> getMyClass() {
    try {
      String className = Files.readString(Path.of("classname.config"));
      return Class.forName(className);
    } catch (IOException | ClassNotFoundException e) {
      throw new RuntimeException("Error while loading class from configuration", e);
    }
  }

  public void run() {
    try {
      throw new Throwable();
    } catch (Throwable e) {
      throw new RuntimeException(e);
    }
  }
}

Describe the target audience Everyone willing to use a boilerplate reduction annotation for handling exceptions but not using @SneakyThrow because it violates java contracts

Additional context If anyone can suggest where to add this functionality in the code (I imagine it's similar to @SneakyThrow) please share info so to attempt a pull request