Class ResultOrProblems<T>
An optional-esque that contains the result of some result-yielding operation where it may have had problems which might have stopped it from producing a result.
Used as a functional alternative to using checked exceptions for user-facing errors, typically where the type of the problem is irrelevant - something the user has done has meant we can't proceed and we need to pass it back to the user with some context to help them fix it.
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaddProblemsTo(Collection<Problem> collection) <U> ResultOrProblems<U>composeFailure(Problem parentProblem) Compose a failed result with a new type and a parent error message.composeProblems(String message, Object... args) Deprecated.For new code, use the i18n Problem-based method below insteadcomposeProblems(BiFunction<Problem.Severity, List<Problem>, Problem> callback) Variant ofcomposeProblems(Problem)that allows the problem to be constructed via a callback.composeProblems(Problem parentProblem) If this result has problems, then this method will return a new ResultOrProblems with a single problem with a new message that has this objects problems as children.drainWarnings(Consumer<Problem> problemConsumer) Removes any warnings or lower from a successfulResultOrProblemsso that get() doesn't produce a warningdrainWarnings(Consumer<Problem> problemConsumer, BiFunction<Problem.Severity, List<Problem>, Problem> callback) Removes any warnings or lower from a successfulResultOrProblemsso that get() doesn't produce a warning.booleanstatic <T> ResultOrProblems<T>Shortcut to ResultOrProblems.failed(Problem.error)static <T> ResultOrProblems<T>Shortcut to ResultOrProblems.failed(Problem.error)static <T> ResultOrProblems<T>static <T> ResultOrProblems<T>failed(Collection<ResultOrProblems<?>> failures) Create a new failedResultOrProblemsthat collects all problems from a set of otherResultOrProblems.static <T> ResultOrProblems<T>static <T> ResultOrProblems<T>static <T> ResultOrProblems<T>failed(ResultOrProblems<?> firstFailure, ResultOrProblems<?>... restFailures) Create a new failedResultOrProblemsthat collects all problems from a set of otherResultOrProblems.filterProblems(Class<?> affects) Filters the Problems based on the class of thing the problem affects, e.g.<U> ResultOrProblems<U>flatMap(BiFunction<T, List<Problem>, ResultOrProblems<U>> mapper) Maps thisResultOrProblemsto another, only if the result has been set.<U> ResultOrProblems<U>flatMap(Function<? super T, ResultOrProblems<U>> mapper) likeflatMap(BiFunction), but appends the problem lists together in a newResultOrProblemsobjectget()Returns the Problems found as a single Problem, rather than a List.Flow control helper for use with ResultOrProblems - seeProblemExceptionfor more details.getOrThrow(Function<Problems, Problems> problemFunction) Flow control helper for use with ResultOrProblems - seeProblemExceptionfor more details.getOrThrow(Problem parent) Flow control helper for use with ResultOrProblems - seeProblemExceptionfor more details.booleanShortcut forhasProblems(Severity.ERROR)inthashCode()booleanbooleanhasProblems(Problem.Severity greaterThanEqualTo) voidCall the given consumer function with the result, only if result is set, else call the consumer<U> UCall the given consumer function with the result, only if result is set, else call the consumer<U> UCall the given consumer function with the result, only if result is set, else call the consumervoidCall the given consumer function with the result, only if result is set<U> Optional<U>ifProblems(Function<List<Problem>, U> function) Call the given function if there were any problems with thisResultOrProblems, returning whatever the function returned.boolean<U> ResultOrProblems<U>Maps the result of thisResultOrProblemsto another result, only if the result has been set.<U> ResultOrProblems<U>Maps the result of thisResultOrProblemsto another result, only if the result has been set, as well as supporting remapping problems one at a time regardless of a result.<U> ResultOrProblems<U>mapOrCombine(Function<T, U> mapper, ResultOrProblems<?>... dependencies) Likemap(Function), but will only map if this and all dependencies succeeded.static <T> ResultOrProblems<T>of(T thing) static <T> ResultOrProblems<T>static <T> ResultOrProblems<T>static <T> ResultOrProblems<T>ofNullable(T thing, List<Problem> withProblems) Constructor where thing may or may not have been successfully created.orElseThrow(Function<List<Problem>, ? extends X> exceptionSupplier) Mirror ofOptional.orElseThrow(Supplier)- throws the given exception if there is no computed result.orElseThrow(Supplier<? extends X> exceptionSupplier) Mirror ofOptional.orElseThrow(Supplier)- throws the given exception if there is no computed result.toString()static ResultOrProblems<Anything>withMoreProblems(Collection<Problem> moreProblems) withMoreProblems(Function<T, List<Problem>> validation) Applies the given validation function to the computed result, and returns a new ResultOrProblems with any additional problems that were foundwithMoreProblems(Problem... moreProblems)
-
Field Details
-
NO_PROBLEMS
-
-
Constructor Details
-
ResultOrProblems
-
-
Method Details
-
of
-
of
-
of
-
ofNullable
Constructor where thing may or may not have been successfully created.
-
failed
Create a new failed
ResultOrProblemsthat collects all problems from a set of otherResultOrProblems. The caller must ensure that there are at least some error level problems among the given arguments.- Type Parameters:
T- An arbitrary generic type- Parameters:
failures- a collection of results with some failures- Returns:
- a new failed ResultOrProblems that includes all problems from the given problems
- Throws:
IllegalArgumentException- if there are no errors among the results
-
failed
public static <T> ResultOrProblems<T> failed(ResultOrProblems<?> firstFailure, ResultOrProblems<?>... restFailures) throws IllegalArgumentException Create a new failed
ResultOrProblemsthat collects all problems from a set of otherResultOrProblems. The caller must ensure that there are at least some error level problems among the given arguments.- Type Parameters:
T- An arbitrary generic type- Parameters:
firstFailure- a possibly failed resultrestFailures- even more possibly failed results- Returns:
- a new failed ResultOrProblems that includes all problems from the given problems
- Throws:
IllegalArgumentException- if there are no errors among the results
-
failed
-
failed
-
error
Shortcut to ResultOrProblems.failed(Problem.error)
-
error
Shortcut to ResultOrProblems.failed(Problem.error)
-
error
-
unchecked
-
getProblems
-
get
- Returns:
- the result of this
ResultOrProblems - Throws:
ResultComputationException- if no result was set, with thisResultOrProblemslist of problems attached to it.
-
getOrThrow
Flow control helper for use with ResultOrProblems - see
ProblemExceptionfor more details.- Returns:
- a computed result if one is present, or throws a
ProblemExceptionwith problems if none. - Throws:
ProblemException- if there is no computed result
-
getOrThrow
Flow control helper for use with ResultOrProblems - see
ProblemExceptionfor more details.- Parameters:
parent- a problem to wrap around any problems that might be present- Returns:
- a computed result if one is present, or throws a
ProblemExceptionwith problems if none. - Throws:
ProblemException- if there is no computed result
-
getOrThrow
Flow control helper for use with ResultOrProblems - see
ProblemExceptionfor more details. This variant gives more control over the problem that ultimately gets included in theProblemException.- Parameters:
problemFunction- a function that will produce a single problem for the ProblemException that is thrown.- Returns:
- a computed result if one is present, or throws a
ProblemExceptionwith problems if none. - Throws:
ProblemException- if there is no computed result
-
getWithProblemsIgnored
- Returns:
- computedResult, regardless of any other conditions. Will return a computedResult even if problems occurred - this function is really here to allow debugging/messaging code to report back a semi-successful object back to the user.
-
drainWarnings
Removes any warnings or lower from a successful
ResultOrProblemsso that get() doesn't produce a warning -
drainWarnings
public ResultOrProblems<T> drainWarnings(Consumer<Problem> problemConsumer, BiFunction<Problem.Severity, List<Problem>, Problem> callback) Removes any warnings or lower from a successful
ResultOrProblemsso that get() doesn't produce a warning.Similar to
drainWarnings(java.util.function.Consumer)except that if non error problems are found then the callback used to get a problem that is then passed to the problemConsumer -
ifProblems
Call the given function if there were any problems with this
ResultOrProblems, returning whatever the function returned. -
isPresent
public boolean isPresent()- Returns:
- true if result is set.
-
ifPresent
Call the given consumer function with the result, only if result is set
-
ifElse
Call the given consumer function with the result, only if result is set, else call the consumer
-
ifElseReturn
Call the given consumer function with the result, only if result is set, else call the consumer
-
ifElseReturn
public <U> U ifElseReturn(Function<T, U> function, Consumer<List<Problem>> elseConsume, U elseReturn) Call the given consumer function with the result, only if result is set, else call the consumer
-
hasProblems
public boolean hasProblems()- Returns:
- true if this
ResultOrProblemshas any problems, regardless of severity.
-
hasProblems
- Returns:
- true if this object's list of problems contain any that are of an equal or greater severity to the given severity parameter.
-
filterProblems
Filters the Problems based on the class of thing the problem affects, e.g. find all the problems that relate to a parameter.
- Parameters:
affects- the type of thing affected by the Problem, e.g. Parameter.class, Step.class- Returns:
- A list of Problems that affect the given class
-
flatMap
like
flatMap(BiFunction), but appends the problem lists together in a newResultOrProblemsobject -
flatMap
Maps this
ResultOrProblemsto another, only if the result has been set. It is up to the BiFunction to produce a new set of problems - normally you want to append problems, so use theFunctionform of this method. -
map
Maps the result of this
ResultOrProblemsto another result, only if the result has been set. -
map
Maps the result of this
ResultOrProblemsto another result, only if the result has been set, as well as supporting remapping problems one at a time regardless of a result.- Parameters:
problemMapper- a function to convert the problem list.
-
mapOrCombine
public <U> ResultOrProblems<U> mapOrCombine(Function<T, U> mapper, ResultOrProblems<?>... dependencies) Like
map(Function), but will only map if this and all dependencies succeeded. A failed result includes problems from this and all dependencies.- Type Parameters:
U- The mapped result type- Parameters:
mapper- a mapping function for a successful resultdependencies- other ResultOrProblems to check for failures before calling the mapping function- Returns:
- a successful result of type or a failed result containing all problems.
-
orElse
- Returns:
- either the set result, or otherThing if result is not set. otherThing can be null.
-
orElse
- Returns:
- either the set result, or otherThing if result is not set. otherThing can be null.
-
orElseGet
- Returns:
- either the set result, or otherThing if result is not set. otherThing can be null.
-
withMoreProblems
- Returns:
- a new
ResultOrProblemsobject that contains the existing list of problems as well as the given list of problems.
-
withMoreProblems
Applies the given validation function to the computed result, and returns a new ResultOrProblems with any additional problems that were found
-
withMoreProblems
- Returns:
- a new
ResultOrProblemsobject that contains the existing list of problems as well as the given list of problems.
-
orElseThrow
public <X extends Throwable> T orElseThrow(Function<List<Problem>, ? extends X> exceptionSupplier) throws XMirror of
Optional.orElseThrow(Supplier)- throws the given exception if there is no computed result.- Throws:
X extends Throwable
-
orElseThrow
Mirror of
Optional.orElseThrow(Supplier)- throws the given exception if there is no computed result.- Throws:
X extends Throwable
-
toString
-
hasErrors
public boolean hasErrors()Shortcut for
hasProblems(Severity.ERROR)- Returns:
- true if there are any errors
-
equals
-
hashCode
public int hashCode() -
composeProblems
Deprecated.For new code, use the i18n Problem-based method below instead -
composeProblems
If this result has problems, then this method will return a new ResultOrProblems with a single problem with a new message that has this objects problems as children. Acts as a conditional shortcut for Problem.composite(resultOr.getProblems()..) - a common pattern when nesting problems with more context, e.g an expression failed that was part of a step, that was part of a pipeline, etc.
-
composeProblems
public ResultOrProblems<T> composeProblems(BiFunction<Problem.Severity, List<Problem>, Problem> callback) Variant of
composeProblems(Problem)that allows the problem to be constructed via a callback. Can be more clear or possibly required if a problem can not be constructed without children.- Parameters:
callback- that will be invoked if there are problems on thisResultOrProblemsobject.- Returns:
- a new
ResultOrProblemswith a single problem that was created bycallback, or the original object if there are no problems on thisResultOrProblemsobject.
-
composeFailure
Compose a failed result with a new type and a parent error message. Will fail if this is not already a failure
-
addProblemsTo
-
getAsSingleProblem
Returns the Problems found as a single Problem, rather than a List. This can be useful for propagating errors via a RiskScapeException. Use this API if: - you're pretty sure you're only ever going to have a single problem in the list. - Or, the code you're dealing with is so generic, there's not a more appropriate object/context to use (i.e. you don't really know what the underlying 'thing' is). Otherwise, use the Problems.foundWith() API instead.
-