T - the type of the underlying result for a successful invocationpublic final class Result<T> extends Object implements org.joda.beans.ImmutableBean, Serializable
This provides a functional approach to error handling, that can be used instead of exceptions. A success result contains a non-null result value. A failure result contains details of the failure that occurred.
Methods using this approach to error handling are expected to return Result<T>
and not throw exceptions. The factory method of(Supplier) and related methods
can be used to capture exceptions and convert them to failure results.
Application code using a result should also operate in a functional style.
Use map(Function) and flatMap(Function) in preference to
isSuccess() and getValue().
Result <Foo> intermediateResult = calculateIntermediateResult(); return intermediateResult.flatMap(foo -> calculateFinalResult(foo, ...));
Results can be generated using the factory methods on this class.
| Modifier and Type | Class and Description |
|---|---|
static class |
Result.Meta<T>
The meta-bean for
Result. |
| Modifier and Type | Method and Description |
|---|---|
static boolean |
allSuccessful(Iterable<? extends Result<?>> results)
Checks if all the results are successful.
|
static boolean |
allSuccessful(Result<?>... results)
Checks if all the results are successful.
|
static boolean |
anyFailures(Iterable<? extends Result<?>> results)
Checks if any of the results are failures.
|
static boolean |
anyFailures(Result<?>... results)
Checks if any of the results are failures.
|
static <T,R> Result<R> |
combine(Iterable<? extends Result<T>> results,
Function<Stream<T>,R> function)
Takes a collection of results, checks if all of them are successes
and then applies the supplied function to the successes wrapping
the result in a success result.
|
<U,R> Result<R> |
combineWith(Result<U> other,
BiFunction<T,U,Result<R>> function)
Combines this result with another result.
|
static long |
countFailures(Iterable<? extends Result<?>> results)
Counts how many of the results are failures.
|
static long |
countFailures(Result<?>... results)
Counts how many of the results are failures.
|
boolean |
equals(Object obj) |
static <R> Result<R> |
failure(Exception cause)
Creates a failed result caused by an exception.
|
static <R> Result<R> |
failure(Exception cause,
String message,
Object... messageArgs)
Creates a failed result caused by an exception.
|
static <R> Result<R> |
failure(Failure failure)
Creates a failed result containing a failure.
|
static <R> Result<R> |
failure(FailureItem failureItem)
Creates a failed result containing a failure item.
|
static <R> Result<R> |
failure(FailureReason reason,
Exception cause)
Creates a failed result caused by an exception with a specified reason.
|
static <R> Result<R> |
failure(FailureReason reason,
Exception cause,
String message,
Object... messageArgs)
Creates a failed result caused by an exception with a specified reason and message.
|
static <R> Result<R> |
failure(FailureReason reason,
String message,
Object... messageArgs)
Creates a failed result specifying the failure reason.
|
static <R> Result<R> |
failure(FailureReason reason,
Throwable cause)
Creates a failed result caused by a throwable with a specified reason.
|
static <R> Result<R> |
failure(FailureReason reason,
Throwable cause,
String message,
Object... messageArgs)
Creates a failed result caused by a throwable with a specified reason and message.
|
static <R> Result<R> |
failure(Iterable<? extends Result<?>> results)
Creates a failed result combining multiple failed results.
|
static <R> Result<R> |
failure(Result<?> failureResult)
Returns a failed result from another failed result.
|
static <R> Result<R> |
failure(Result<?> result1,
Result<?> result2,
Result<?>... results)
Creates a failed result combining multiple failed results.
|
static <R> Result<R> |
failure(Throwable cause)
Creates a failed result caused by a throwable.
|
static <R> Result<R> |
failure(Throwable cause,
String message,
Object... messageArgs)
Creates a failed result caused by a throwable.
|
static <T,R> Result<R> |
flatCombine(Iterable<? extends Result<T>> results,
Function<Stream<T>,Result<R>> function)
Takes a collection of results, checks if all of them are successes
and then applies the supplied function to the successes.
|
<R> Result<R> |
flatMap(Function<? super T,Result<R>> function)
Processes a successful result by applying a function that returns another result.
|
Optional<T> |
get()
Returns the result value if calculated successfully, empty if a failure occurred.
|
Failure |
getFailure()
Returns the failure instance indicating the reason why the calculation failed.
|
T |
getValue()
Returns the actual result value if calculated successfully, throwing an
exception if a failure occurred.
|
T |
getValueOrElse(T defaultValue)
Returns the actual result value if calculated successfully, or the specified
default value if a failure occurred.
|
T |
getValueOrElseApply(Function<Failure,T> mapper)
Returns the actual result value if calculated successfully, else the
specified function is applied to the
Failure that occurred. |
int |
hashCode() |
void |
ifFailure(Consumer<Failure> consumer)
Executes the given consumer if the result represents a failure.
|
void |
ifSuccess(Consumer<? super T> consumer)
Executes the given consumer if the result represents a successful call and has a result available.
|
boolean |
isFailure()
Indicates if this result represents a failure.
|
boolean |
isSuccess()
Indicates if this result represents a successful call and has a result available.
|
<R> Result<R> |
map(Function<? super T,? extends R> function)
Processes a successful result by applying a function that alters the value.
|
static Result.Meta |
meta()
The meta-bean for
Result. |
Result.Meta<T> |
metaBean() |
static <R> Result.Meta<R> |
metaResult(Class<R> cls)
The meta-bean for
Result. |
static <T> Result<T> |
of(Supplier<T> supplier)
Creates a success
Result wrapping the value produced by the
supplier. |
static <R> Result<R> |
ofNullable(R value)
Returns a success result containing the value if it is non-null, else returns a failure result
with a reason of
FailureReason.MISSING_DATA and message to say an unexpected null was found. |
static <R> Result<R> |
ofNullable(R value,
FailureReason reason,
String message,
Object... messageArgs)
Returns a success result containing the value if it is non-null, else returns a failure result
with the specified reason and message.
|
Stream<T> |
stream()
Converts this result to a stream.
|
static <R> Result<R> |
success(R value)
Creates a successful result wrapping a value.
|
String |
toString() |
static <T> Result<T> |
wrap(Supplier<Result<T>> supplier)
Creates a
Result wrapping the result produced by the supplier. |
public static <R> Result<R> success(R value)
This returns a successful result object for the non-null value.
Note that passing an instance of Failure to this method would
be a programming error.
R - the type of the valuevalue - the result valuepublic static <R> Result<R> failure(FailureReason reason, String message, Object... messageArgs)
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultreason - the result reasonmessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <T> Result<T> of(Supplier<T> supplier)
Result wrapping the value produced by the
supplier.
Note that if the supplier throws an exception, this will be caught
and converted to a failure Result.
T - the type of the valuesupplier - supplier of the result valueResult wrapping the value produced by the supplierpublic static <T> Result<T> wrap(Supplier<Result<T>> supplier)
Result wrapping the result produced by the supplier.
Note that if the supplier throws an exception, this will be caught
and converted to a failure Result.
T - the type of the result valuesupplier - supplier of the resultResult produced by the supplierpublic static <R> Result<R> failure(Throwable cause)
The failure will have a reason of ERROR.
R - the expected type of the resultcause - the cause of the failurepublic static <R> Result<R> failure(Exception cause)
The failure will have a reason of ERROR.
R - the expected type of the resultcause - the cause of the failurepublic static <R> Result<R> failure(Throwable cause, String message, Object... messageArgs)
The failure will have a reason of ERROR.
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultcause - the cause of the failuremessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <R> Result<R> failure(Exception cause, String message, Object... messageArgs)
The failure will have a reason of ERROR.
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultcause - the cause of the failuremessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <R> Result<R> failure(FailureReason reason, Throwable cause)
R - the expected type of the resultreason - the result reasoncause - the cause of the failurepublic static <R> Result<R> failure(FailureReason reason, Exception cause)
R - the expected type of the resultreason - the result reasoncause - the cause of the failurepublic static <R> Result<R> failure(FailureReason reason, Throwable cause, String message, Object... messageArgs)
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultreason - the result reasoncause - the cause of the failuremessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <R> Result<R> failure(FailureReason reason, Exception cause, String message, Object... messageArgs)
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultreason - the result reasoncause - the cause of the failuremessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <R> Result<R> failure(Result<?> failureResult)
This method ensures the result type matches the expected type. If the specified result is a successful result then an exception is thrown.
R - the expected result typefailureResult - a failure resultIllegalArgumentException - if the result is a successpublic static <R> Result<R> failure(Result<?> result1, Result<?> result2, Result<?>... results)
The input results can be successes or failures, only the failures will be included in the created result.
Intended to be used with anyFailures(Result...).
if (Result.anyFailures(result1, result2, result3) {
return Result.failure(result1, result2, result3);
}
R - the expected type of the resultresult1 - the first resultresult2 - the second resultresults - the rest of the resultsIllegalArgumentException - if all of the results are successespublic static <R> Result<R> failure(Iterable<? extends Result<?>> results)
The input results can be successes or failures, only the failures will be included in the created result.
Intended to be used with anyFailures(Iterable).
if (Result.anyFailures(results) {
return Result.failure(results);
}
R - the expected type of the resultresults - multiple results, of which at least one must be a failure, not emptyIllegalArgumentException - if results is empty or contains nothing but successespublic static <R> Result<R> failure(Failure failure)
This is useful for converting an existing Failure instance to a result.
R - the expected type of the resultfailure - details of the failurepublic static <R> Result<R> failure(FailureItem failureItem)
This is useful for converting an existing FailureItem instance to a result.
R - the expected type of the resultfailureItem - details of the failurepublic static <R> Result<R> ofNullable(R value, FailureReason reason, String message, Object... messageArgs)
This is useful for interoperability with APIs that return null, for example Map.get(), where
a missing value should be treated as a failure.
The message is produced using a template that contains zero to many "{}" placeholders.
Each placeholder is replaced by the next available argument.
If there are too few arguments, then the message will be left with placeholders.
If there are too many arguments, then the excess arguments are appended to the
end of the message. No attempt is made to format the arguments.
See Messages.format(String, Object...) for more details.
R - the expected type of the resultvalue - the potentially null valuereason - the reason for the failuremessage - a message explaining the failure, uses "{}" for inserting messageArgsmessageArgs - the arguments for the messagepublic static <R> Result<R> ofNullable(R value)
FailureReason.MISSING_DATA and message to say an unexpected null was found.
This is useful for interoperability with APIs that can return null but where null is not expected.
R - the expected type of the resultvalue - the potentially null valuepublic static boolean allSuccessful(Result<?>... results)
results - the results to checkpublic static boolean allSuccessful(Iterable<? extends Result<?>> results)
results - the results to checkpublic static boolean anyFailures(Result<?>... results)
results - the results to checkpublic static boolean anyFailures(Iterable<? extends Result<?>> results)
results - the results to checkpublic static long countFailures(Result<?>... results)
results - the results to checkpublic static long countFailures(Iterable<? extends Result<?>> results)
results - the results to checkpublic static <T,R> Result<R> combine(Iterable<? extends Result<T>> results, Function<Stream<T>,R> function)
If an exception is thrown when the function is applied, this will
be caught and a failure Result returned.
The following code shows where this method can be used. The code:
Set<Result<MyData>> results = goAndGatherData();
if (Result.anyFailures(results)) {
return Result.failure(results);
} else {
Set<FooData> combined =
results.stream()
.map(Result::getValue)
.map(MyData::transformToFoo)
.collect(toSet());
return Result.success(combined);
}
can be replaced with:
Set<Result<MyData>> results = goAndGatherData();
return Result.combine(results, myDataStream ->
myDataStream
.map(MyData::transformToFoo)
.collect(toSet())
);
T - the type of the values held in the input resultsR - the type of the values held in the transformed resultsresults - the results to be transformed if they are all successesfunction - the function to apply to the stream of results if they were all successespublic static <T,R> Result<R> flatCombine(Iterable<? extends Result<T>> results, Function<Stream<T>,Result<R>> function)
If an exception is thrown when the function is applied, this will
be caught and a failure Result returned.
The following code shows where this method can be used. The code:
Set<Result<MyData>> results = goAndGatherData();
if (Result.anyFailures(results)) {
return Result.failure(results);
} else {
Set<FooData> combined =
results.stream()
.map(Result::getValue)
.map(MyData::transformToFoo)
.collect(toSet());
return doSomethingReturningResult(combined); // this could fail
}
can be replaced with:
Set<Result<MyData>> results = goAndGatherData();
return Result.flatCombine(results, myDataStream -> {
Set<CombinedData> combined =
myDataStream
.map(MyData::transformToFoo)
.collect(toSet());
return doSomethingReturningResult(combined); // this could fail
});
T - the type of the values held in the input resultsR - the type of the values held in the transformed resultsresults - the results to be transformed if they are all successesfunction - the function to apply to the stream of results if they were all successespublic boolean isSuccess()
This is the opposite of isFailure().
public void ifSuccess(Consumer<? super T> consumer)
consumer - the consumer to be decoratedpublic boolean isFailure()
This is the opposite of isSuccess().
public void ifFailure(Consumer<Failure> consumer)
consumer - the consumer to be decoratedpublic Optional<T> get()
public T getValue()
If this result is a failure then an IllegalStateException will be thrown.
To avoid this, call isSuccess() or isFailure() first.
Application code is recommended to use map(Function) and
flatMap(Function) in preference to this method.
IllegalStateException - if called on a failure resultpublic T getValueOrElse(T defaultValue)
If this result is a success then the result value is returned. If this result is a failure then the default value is returned. The default value may be null.
Application code is recommended to use map(Function) and
flatMap(Function) in preference to this method.
defaultValue - the default value to return if the result is a failurepublic T getValueOrElseApply(Function<Failure,T> mapper)
Failure that occurred.
If this result is a success then the result value is returned. If this result is a failure then the function is applied to the failure. The function must not be null.
This method can be used in preference to getValueOrElse(Object)
when the default value is expensive to create. In such cases, the
default value will get created on each call, even though it will be
immediately discarded if the result is a success.
mapper - function used to generate a default value. The function
has no obligation to use the input Failure (in other words it can
behave as a Supplier<T> if desired).public Failure getFailure()
If this result is a success then an an IllegalStateException will be thrown.
To avoid this, call isSuccess() or isFailure() first.
IllegalStateException - if called on a success resultpublic <R> Result<R> map(Function<? super T,? extends R> function)
This operation allows post-processing of a result value. The specified function represents a conversion to be performed on the value.
If this result is a success, then the specified function is invoked.
The return value of the specified function is returned to the caller
wrapped in a success result. If an exception is thrown when the function
is invoked, this will be caught and a failure Result returned.
If this result is a failure, then this is returned.
The specified function is not invoked.
For example, it allows a double to be converted to a string:
result = ... return result.map(value -> Double.toString(value));
R - the type of the value in the returned resultfunction - the function to transform the value withpublic <R> Result<R> flatMap(Function<? super T,Result<R>> function)
This operation allows chaining of function calls that produce a result. The specified function will typically call another method that returns a result.
If this result is a success, then the specified function is invoked.
The return value of the specified function is returned to the caller and may be
a success or failure. If an exception is thrown when the function
is invoked, this will be caught and a failure Result returned.
If this result is a failure, then an equivalent failure is returned. The specified function is not invoked.
For example,
result = ... return result.flatMap(value -> doSomething(value));
R - the type of the value in the returned resultfunction - the function to transform the value withpublic <U,R> Result<R> combineWith(Result<U> other, BiFunction<T,U,Result<R>> function)
This operation allows two results to be combined handling succeess and failure.
If both results are a success, then the specified function is invoked to combine them. The return value of the specified function is returned to the caller and may be a success or failure.
If either result is a failure, then a combination failure is returned. The specified function is not invoked.
result1 = ... result2 = ... return result1.combineWith(result2, (value1, value2) -> doSomething(value1, value2));
U - the type of the value in the other resultR - the type of the value in the returned resultother - another resultfunction - a function for combining values from two resultspublic Stream<T> stream()
If this result is a success then a single element stream containing the result value is returned. If this result is a failure then an empty stream is returned.
public static Result.Meta meta()
Result.public static <R> Result.Meta<R> metaResult(Class<R> cls)
Result.R - the bean's generic typecls - the bean's generic typepublic Result.Meta<T> metaBean()
metaBean in interface org.joda.beans.BeanCopyright 2009-Present by OpenGamma Inc. and individual contributors
Apache v2 licensed
Additional documentation can be found at strata.opengamma.io.