This library is inspired by FluentResults and aims to reduce the reliance on exceptions for controlling the flow of code, particularly replacing the traditional use of try-catch blocks for error handling.
The Result pattern encapsulates the outcome of operations in a robust manner, supporting the following key features:
- Status Indication: Each
Resultinstance denotes whether an operation was successful or failed. - Return Value Handling: It holds the return value of an operation. For operations without a return value (void
operations), a special
NoValueclass representation is used. Attempting to retrieve a value fromResult<NoValue>results in an exception. - Reasons for Outcome: The
Resultcan contain reasons for its status, allowing eitherSuccessorFailurestates, with support for customReasonimplementations for detailed error handling and messaging.
import com.vincentdao.result.NoValue;
import com.vincentdao.result.Result;
public static void main(String[] args) {
// Successful Result with value
Result<Integer> valueResult = Result.successful()
.withValue(1);
// Successful Result with no value
Result<NoValue> noValueResult = Result.successful()
.withNoValue();
}import com.vincentdao.result.NoValue;
import com.vincentdao.result.Result;
public static void main(String[] args) {
// Failed Result
Result<Integer> failedValueResult = Result.failed();
// Can also represent no-value one
Result<NoValue> failedNoValue = Result.failed();
}import com.vincentdao.result.Result;
public static void main(String[] args) {
Result<Integer> result = Result.successful()
.withValue(1);
// Get the value
Integer value = result.value();
}import com.vincentdao.result.Result;
import com.vincentdao.result.trace.DefaultSuccess;
import com.vincentdao.result.trace.Success;
import java.util.Collection;
import java.util.LinkedList;
public static void main(String[] args) {
Result<Integer> result = Result.successful()
.withValue(1);
// Default success with message
result.withSuccessMessage("Success message");
// Success instance
result.withSuccess(new DefaultSuccess("Success message"));
// Collection of Success
Collection<Success> successes = new LinkedList<>();
successes.add(new DefaultSuccess("Success message."));
result.withSuccesses(successes);
// Same operations above for Failure & Reason...
}import com.vincentdao.result.Result;
import com.vincentdao.result.trace.ExceptionalFailure;
import com.vincentdao.result.trace.Failure;
import com.vincentdao.result.trace.Reason;
import com.vincentdao.result.trace.Success;
import java.util.Collection;
public static void main(String[] args) {
Result<Integer> result = Result.failed();
// Get all reasons
Collection<Reason> reasons = result.reasons();
// Only Success reasons
Collection<Success> successes = result.successes();
// Only Failure reasons
Collection<Failure> failures = result.failures();
// Custom filtering
Collection<Reason> filteredReasons = result
.reasonsFiltered(reason -> reason instanceof ExceptionalFailure);
}Note: adding a Failure to the currently successful Result will make it a failed Result.
import com.vincentdao.result.Result;
public static void main(String[] args) {
Result<Integer> successfulResult = Result.successful()
.withValue(1);
// Special case! Adding a Failure to the currently successful Result will make it a failed Result!
successfulResult.withFailureMessage("Failure message.");
System.out.println(successfulResult.isSuccessful()); // false
System.out.println(successfulResult.isFailed()); // true
}When receiving a Result instance, you can inspect its status, retrieve the value if the operation was successful, or
examine the failed reasons if not.
import com.vincentdao.result.NoValue;
import com.vincentdao.result.Result;
public static void main(String[] args) {
Result<NoValue> result = doSomething();
if (result.isSuccessful()) {
// Logic for successful operation
} else {
// Logic for failed operation
}
}Although the library provides Success and Failure as default reasons for operation outcomes, it is possible to
implement custom reasons by extending these base classes for more granular control over error representation.
import com.vincentdao.result.trace.Failure;
public class CustomFailureReason extends Failure {
// Implementation details
}Note that Result instances are not thread-safe and are intended to be used within the context of a single operation.
They should be handled accordingly to avoid concurrency issues.
This project is licensed under MIT License.