DEV Community

Cover image for ๐ŸŽฃ Catchy โ€” A Cleaner Way to Handle Exceptions in Java
jvm-Monster
jvm-Monster

Posted on

๐ŸŽฃ Catchy โ€” A Cleaner Way to Handle Exceptions in Java

If you're tired of writing the same try/catch block five times a day... youโ€™re not alone.

Java gives you full control over error handling, but with great power comes repetitive boilerplate. Every time we wrap risky code, we write the same dance:

try {
    var data = risky();
    log.info("Success: {}", data);
} catch (Exception e) {
    log.error("Something broke", e);
}
Enter fullscreen mode Exit fullscreen mode

And thatโ€™s just success/failure. What about retrying? Backoff? Fallback values?
Youโ€™ll be adding more layers than a wedding cake ๐ŸŽ‚


Thatโ€™s why I built Catchy

Catchy is a tiny utility that makes Java error handling:

  • โœ… Fluent and chainable
  • ๐Ÿ” Retryable (with backoff)
  • ๐Ÿ”„ Transformable (with .map())
  • ๐Ÿ”ฅ SLF4J-loggable
  • โ™ป๏ธ Recoverable with fallback values
  • ๐Ÿ’ก Developer-friendly

The Before & After

Before:

try {
    var data = risky();
    System.out.println(data);
} catch (Exception e) {
    e.printStackTrace();
}
Enter fullscreen mode Exit fullscreen mode

After:

TryWrapper.tryCatch(() -> risky())
    .logIfFailure(logger)
    .onSuccess(val -> System.out.println(val))
    .onFailure(err -> System.err.println(err.getMessage()));
Enter fullscreen mode Exit fullscreen mode

Same control. Cleaner code.


๐Ÿง  Why Catchy?

Catchy doesnโ€™t replace exceptions โ€” it wraps them with structure. You get:

โœ… Less boilerplate

tryCatch(() -> riskyCode()) returns a Result<T> that you can handle safely.

๐Ÿ” Retry logic

With optional delay and exponential backoff:

TryWrapper.tryCatch(() -> connect(), null, 3, 200, true);
Enter fullscreen mode Exit fullscreen mode

โ™ป๏ธ Recovery

Gracefully fallback:

.recover(() -> "default")
.recoverWithValue("fallback")
.recoverWithMessage("Uh-oh!")
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”„ Transform values

You can transform the success result using .map():

.map(val -> val + "!")
Enter fullscreen mode Exit fullscreen mode

If it fails, it gets caught โ€” safely.

๐Ÿ”ฅ Smart logging

SLF4J logging is built-in and detects exception severity automatically:

Exception Type Level
NullPointerException WARN
RuntimeException ERROR
Checked exceptions INFO

โœ… Real-World Example

TryWrapper.tryCatch(() -> callApi())
    .recover(() -> "fallback")
    .map(val -> val + "!")
    .logIfFailure(logger)
    .onSuccess(System.out::println)
    .onFailure(err -> System.err.println("Fail: " + err.getMessage()));
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ฆ Get it via JitPack

<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

<dependency>
  <groupId>com.github.justme8code</groupId>
  <artifactId>catchy</artifactId>
  <version>v1.0.0</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”— GitHub
๐Ÿ”— JitPack


๐Ÿš€ Why I made Catchy

I'm a Java dev who got tired of writing the same try/catch block over and over.

Catchy was built for real-world codebases where you want control but donโ€™t want clutter. It's inspired by functional-style Try, but designed for normal devs who just want clean, readable exception handling.


๐Ÿ™ Feedback welcome!

If youโ€™ve been fighting Javaโ€™s exception boilerplate, give Catchy a spin.
PRs, stars, and suggestions all welcome โค๏ธ

Top comments (0)