-1

I have a lot of this type code in my app:

String authUserId = null;

try {
  authUserId = webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
} catch (Exception e) {
  // do nothing
}

With each fragment goal is to assign a value if the method did not throw, null otherwise. And although the code above works it certainly looks redundant and not simplified.

What Java library can make this code more fluent? Like:

String authUserId = Try<String>.of(try -> {
   return webTokenService.readUserIdFromToken(app.getMasterKey(), authToken);
});

or something more simpler.

UPDATE:

Using Vavr library

<dependency>
  <groupId>io.vavr</groupId>
  <artifactId>vavr</artifactId>
  <version>0.10.3</version>
</dependency>

Solved this with:

String authUserId = Try.of(() -> webTokenService.readUserIdFromToken(app.getMasterKey(), authToken)).get();

quarks
  • 33,478
  • 73
  • 290
  • 513

2 Answers2

2

Given that silently swallowing exceptions is dumb, none.

It's entirely trivial to write such a thing yourself:

class ShootMyselfInLegToolkit {
    @FunctionalInterface
    public interface PermissiveSupplier<T> {
        T supply() throws Exception;
    }

    public <T> T ohMyLegs(PermissiveSupplier<T> supplier) {
        try {
            return supplier.supply();
        } catch (Exception itHurts) {
            return null; // dear lord.
        }
    }
}

If you really wanna shove that in a library, by all means.

The slightly-less-silly functional libraries work like this: You supply both a (permissive - java's own j.u.f.Supplier cannot do this) supplier and an exception handler, so it looks like:

Tool.tryGet(() -> Files.readAllLines(Paths.get("foo.txt")), ioex -> { code to handle the exception });

You don't just get to go: Hey, no brackets, so I never press enter, and therefore this is 'fewer lines of code' and therefore, 'simpler', that's.. well, a very strange mode of thinking you got there.

What, in your words, does 'fluent' even mean? I recognize the term as applied to setters, getters, and builder methods, and it means: "No get/set prefix". That obviously doesn't apply here, so you clearly think it means something else. It's not in the java lang spec, so perhaps elaborate.

I fail to see how any of this stuff is simpler to understand or easier to program for, aside from silly style fights. I'd think most would agree that introducing a whole bunch of crazy libraries JUST because you find the commonly used style in the java community abhorrent - that's a bad way out. Writing code in a non-idiomatic fashion is a bad idea, regardless of language and regardless of how much you hate the common style. Just use a different language, or adjust your style tastes. Easier said than done, perhaps, but nevertheless - the better idea, by far.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • I was going to suggest `BadIdea.doItAnyway()` as the signature, but I like yours better. My version uses `Callable` instead of a custom interface though. – erickson Sep 22 '20 at 20:26
  • @rzwitserloot it's not really just about the brackets, that just a first step in having more maintainable code and more things that is out of the scope to the question to elaborate, also your code is a pure syntax error. – quarks Sep 22 '20 at 20:56
  • 1
    @quarks an accidental extra @ snuck in there; removed from the code, which now compiles fine. – rzwitserloot Sep 22 '20 at 21:16
1

If you swallow the exception completely this is not really best practice. There is a nice article about Exception from Baeldung:

The above is called swallowing an exception. Most of the time, it would be a little mean for us to do this because it doesn't address the issue and it keeps other code from being able to address the issue, too.

I have found a library that implements this behaviour. However, it has not been maintained for some time. For this reason I would rather recommend Vavr. It is still necessary to handle the exception. A further tutorial is also available from Baeldung. In the documentation there is a small example of dividing two numbers:

int divide(int dividend, int divisor) {
    return dividend / divisor;
}

Try<Integer> divide(Integer dividend, Integer divisor) {
    return Try.of(() -> dividend / divisor);
}
flaxel
  • 4,173
  • 4
  • 17
  • 30