Automatic exception wrapper in java There's a lot of place in my code where I need to do something like this


public static void read(DataInputStream stream) throws IOException
{
  try
  {
      Object thing = getById(stream.readInt());
  }
  catch(IllegalArgumentException ex)
  {
      throw new IOException(ex); // do not throw IllegalArgumentException if the corrupted data points to invalid things
  }
}

public static Object getById(int id)
{
    for(Object thing : things)
        if(thing.getId() == id)
            return thing;

  throw new IllegalArgumentException("Thing with id " + id + " does not exist!");
}



I like the fact that read() only throws IOExceptions and wrap any detail of internal failure with IOException as having those failures are caused by having corrupted data from the stream. (And corrupted data should return IOException, could return something else but the idea is the same).

What I really don't like is the tedious process of wrapping all my exceptions everytime and incrementing the number of indents I have just to indicate that IllegalArgumentException becomes IOException. An annotation like this


@WrapExcept(IllegalArgumentException.class, ex -&gt; new IOException(ex))
public static void read(DataInputStream stream) throws IOException
{
  Object thing = getById(stream.readInt());
}



would be perfect but I have no idea how it could be possible. The best I could come up with is something along the lines of

@FunctionalInterface
public interface ThrowingCall&lt;R, E extends Throwable&gt;
{
    R call() throws E;
}

public static &lt;R, W extends Throwable, E extends Throwable, T extends Throwable&gt;
R wrapExcept(ThrowingCall&lt;R, T&gt; call, Class&lt;W&gt; exType, Function&lt;W, E&gt; wrapper) throws E, T
{
    try
    {
        return call.call();
    }
    catch(Throwable t)
    {
        if(exType.isInstance(t))
            throw wrapper.apply(exType.cast(t));
        throw t;
    }
}

public static void read() throws IOException
{
    Object thing = wrapExcept(() -&gt; getById(3), IllegalArgumentException.class, ex -&gt; new IOException(ex));
}


Any idea to make this code look likes less verbose? Obviously what I want to improve is the read() call's readability. Also I'm not sure how ThrowingCall could be replaced by something more standard.
This looks like something Optionals can handle, so:

public static Optional&lt;Object&gt; getById(int id) {
    for(Object thing : things) {
        if(thing.getId() == id) {
            return Optional.of(thing);
        }
    }

    return Optional.empty();
}


Now in your read code, you can simply do this:

public static void read(DataInputStream stream) throws IOException {
    Object thing = getById(stream.readInt())
                       .orElseThrow(() -&gt; new IOException("Could not find Id"));

    // Do something with thing
}