Vessel is a lightweight, type-safe functional error-handling library for Modern Java (21+).
It replaces the "hidden trapdoor" of Runtime Exceptions with explicit, composable Result types, allowing you to
treat errors as first-class values. No more fragmented try-catch blocks—just smooth, declarative data pipelines.
In standard Java, an exception interrupts the flow and forces the stack to unwind. In functional programming, we use the Railway Oriented Programming pattern.
- Success Track: Data flows through your transformations (
map,flatMap). - Failure Track: If an error occurs, the data is shunted to a failure track, and subsequent operations are safely bypassed until you are ready to handle the error.
- Sealed Hierarchies: Leverages Java 21
sealed interfacesfor compile-time exhaustiveness. - Pattern Matching: Integrates natively with Record patterns in
switchexpressions. - Zero Dependencies: Pure Java, high performance, and tiny footprint.
// Lift risky code into a Vessel
Vessel<User, Err> user = Vessel.lift(() -> repository.find(id));
// Chain operations safely
Vessel<String, Err> result = user
.filter(User::isActive, Err.USER_INACTIVE)
.flatMap(this::getPreferences)
.map(Prefs::getTheme);
// Pattern match the outcome
String theme = switch (result) {
case Success(var val) -> val;
case Failure(var err) -> "default-dark";
};This roadmap outlines the evolution of the library from core types to advanced concurrency tools.
Focus: Establishing the Monadic core.
- Core Types: Implement Vessel<V, E>
- Functor Ops: Implement .map(Function<V, U>) to transform values.
- Monad Ops: Implement .flatMap(Function<V, Vessel<U, E>>) for operation chaining.
- Inspection: Add isSuccess() and isFailure() utility methods.
Focus: Making Vessel play nice with standard Java libraries.
- Vessel.lift(): Static factory to catch Exception and wrap into a Failure.
- Side-Effect Hooks: peek(Consumer) and peekError(Consumer) for logging/telemetry.
Focus: Domain-specific logic and error recovery.
- mapError: Transform error types (e.g., SQLException → DatabaseError).
- recover: Jump back from the Failure track using a fallback function.
- filter: Convert a Success to a Failure based on a Predicate.
Focus: Coordinating multiple independent results.
- zip: Combine two independent Vessels into a single result (e.g., merging two API calls).
- oneOf: Choose one of two independent Vessels into a single result. (If both are success the first wins)
- sequence: Transform List<Vessel<V, E>> into Vessel<List, E>.
- traverse: Map a list of items to Vessels and sequence them in a single pass.
Focus: Performance and high-scale execution.
- Stream Collector: A custom Collector to gather a stream of results into one Vessel.
- AsyncVessel: Create a specialized wrapper for CompletableFuture<Vessel<V, E>>.