Interface Result<T,E>

Type Parameters:
T - The type of an Ok value, meaning that the operation has completed successfully.
E - The type of an Err value, meaning that the operation has failed with some kind of error.
All Known Implementing Classes:
Err, Ok

public interface Result<T,E>
A result type represents the output of an operation with two possible outcomes. The operation can either yield an Ok, in which case it was performed successfully and without any errors, or it can be an Err, meaning that something unexpected or invalid occurred. This could be anything from a user supplying an incorrect value to a network connection closing unexpectedly.

Normally JVM languages would handle these conditions with exceptions, but doing so can lead to control flow which is difficult to keep track of. With a result type, all conditions are covered by virtue of being correctly typed.

  • Method Summary

    Modifier and Type
    Method
    Description
    <U> Result<U,E>
    and(Result<U,E> result)
    Returns the provided argument if the result is Ok and propagates the original Err otherwise.
    <U> Result<U,E>
    andThen(Function<T,Result<U,E>> resultFn)
    Apply a fallible operation to the wrapped value if the result is Ok.
    err()
    Get the Err value if it exists.
    static <T, E> Err<T,E>
    err(E e)
    An Err indicates that a fallible operation has failed and yielded an error value.
    expect(String errorMessage)
    Return the value if Ok, otherwise throw an exception with a custom error message.
    <F extends Throwable>
    T
    expect(Function<E,F> mapping)
    Returns the value or throws a caller-defined exception.
    expectErr(String errorMessage)
    Return the value if Err, otherwise throw an exception with a custom error message.
    <F extends Throwable>
    E
    expectErr(Function<T,F> mapping)
    Returns the value or throws a caller-defined exception.
    boolean
    Indicates whether the wrapped value is an Err.
    boolean
    Indicates whether the wrapped value is an Ok.
    <U> Result<U,E>
    map(Function<T,U> mapping)
    Apply a transformation to the wrapped value if the result is Ok.
    <F> Result<T,F>
    mapErr(Function<E,F> mapping)
    Apply a transformation to the wrapped value if the result is an Err.
    void
    match(Consumer<T> ifOk, Consumer<E> ifErr)
    Apply a lambda with no return type to the value of a result.
    <U> U
    match(Function<T,U> ifOk, Function<E,U> ifErr)
    Apply a transformation to the value of a result.
    ok()
    Get the Ok value if it exists.
    static <T, E> Ok<T,E>
    ok(T t)
    An Ok indicates that a fallible operation has been performed successfully and that the caller has received their desired result.
    <F> Result<T,F>
    or(Result<T,F> result)
    Returns the provided argument if the result is an Err and propagates the original Ok value otherwise.
    <F> Result<T,F>
    orElse(Function<E,Result<T,F>> resultFn)
    Apply a fallible operation to the wrapped value if the result is an Err.
    static <T, E extends Throwable>
    Result<T,E>
    tryOr(CheckedSupplier<T,E> supplier, Class<E> cls)
    Attempts to execute a fallible operation and returns any exceptions thrown during execution as the error type.
    Retrieve the Ok value or throw an exception if the result is an Err.
    Retrieve the Err value or throw an UnwrapException if the result is Ok.
  • Method Details

    • ok

      static <T, E> Ok<T,E> ok(@NotNull T t)
      An Ok indicates that a fallible operation has been performed successfully and that the caller has received their desired result.
      Type Parameters:
      T - the type of T.
      E - the type of any errors that the fallible operation might produce. In the Ok case this type is unused, but knowing it is important for building robust error handling.
      Parameters:
      t - the output value of the fallible operation.
      Returns:
      an Ok result wrapping t.
    • err

      static <T, E> Err<T,E> err(@NotNull E e)
      An Err indicates that a fallible operation has failed and yielded an error value.
      Type Parameters:
      T - the type of the value that the fallible operation provides on success. In the Err case this type is unused, but knowing it is important for building robust error handling.
      E - the type of e.
      Parameters:
      e - the value of the error. This can be any object and does not need to be a subclass of Throwable. If an exception needs to be thrown on an error, use the unwrap or expect methods.
      Returns:
      an Err result wrapping e.
    • isOk

      boolean isOk()
      Indicates whether the wrapped value is an Ok.
      Returns:
      true if the wrapper is Ok, otherwise false.
    • isErr

      boolean isErr()
      Indicates whether the wrapped value is an Err.
      Returns:
      true if the wrapper is Err, otherwise false.
    • ok

      Optional<T> ok()
      Get the Ok value if it exists.
      Returns:
      the underlying value if the result is Ok, otherwise the value will be empty.
      See Also:
    • err

      Optional<E> err()
      Get the Err value if it exists.
      Returns:
      the underlying value if the result is an Err, otherwise the value will be empty.
      See Also:
    • unwrap

      T unwrap() throws UnwrapException
      Retrieve the Ok value or throw an exception if the result is an Err.
      Returns:
      the value of Ok without an Optional wrapper.
      Throws:
      UnwrapException - if the result is not Ok.
    • unwrapErr

      E unwrapErr() throws UnwrapException
      Retrieve the Err value or throw an UnwrapException if the result is Ok. If the error is a Throwable, it will not be thrown. To throw a custom error, use expect(Function).
      Returns:
      the value of Err without an Optional wrapper.
      Throws:
      UnwrapException - if the result is not Err.
    • expect

      T expect(String errorMessage) throws UnwrapException
      Return the value if Ok, otherwise throw an exception with a custom error message.
      Parameters:
      errorMessage - The message to accompany the UnwrapException if thrown.
      Returns:
      The value, if Ok.
      Throws:
      UnwrapException - If the result is an Err.
    • expect

      <F extends Throwable> T expect(Function<E,F> mapping) throws F
      Returns the value or throws a caller-defined exception.
      Type Parameters:
      F - Type of the thrown exception.
      Parameters:
      mapping - Lambda for creating the thrown exception.
      Returns:
      The value, if Ok.
      Throws:
      F - Thrown if the result is an Err.
    • expectErr

      E expectErr(String errorMessage) throws UnwrapException
      Return the value if Err, otherwise throw an exception with a custom error message.
      Parameters:
      errorMessage - The message to accompany the UnwrapException if thrown.
      Returns:
      The value, if Err.
      Throws:
      UnwrapException - If the result is Ok.
    • expectErr

      <F extends Throwable> E expectErr(Function<T,F> mapping) throws F
      Returns the value or throws a caller-defined exception.
      Type Parameters:
      F - Type of the thrown exception.
      Parameters:
      mapping - Lambda for creating the thrown exception.
      Returns:
      The value, if Err.
      Throws:
      F - Thrown if the result is Ok.
    • match

      <U> U match(Function<T,U> ifOk, Function<E,U> ifErr)
      Apply a transformation to the value of a result.

      In the example below, the parseArgs function attempts to convert a user-provided string to a list of integers, but failing that returns its input unmodified. The output of the function is then used to determine the number of valid user-provided arguments and do some additional logging for convenience.

      
       Result<List<Integer>, String> parsed = parseArgs(input);
       int validArgs = parsed.match(
           ok -> ok.size(),
           err -> {
               log.warn("The provided input could not be parsed: \"{}\"", err);
               return 0;
           }
       );
       
      Note that unlike map(Function), both the Ok and Err values must be mapped to a single output type.
      Type Parameters:
      U - the type of the value to be returned after the transformations are applied. Both transformations must converge to this type.
      Parameters:
      ifOk - the transformation that is applied to the underlying data if the result is Ok.
      ifErr - the transformation that is applied to the underlying data if the result is an Err.
      Returns:
      a value of type U after applying one of the two provided transformations.
    • match

      void match(Consumer<T> ifOk, Consumer<E> ifErr)
      Apply a lambda with no return type to the value of a result.

      This is useful for things which produce side effects such as logging. In contrast to match(Function, Function), no output can be obtained from an invocation of this method. In the example below, some informational logging is performed on the parseArgs function.

      
       Result<List<Integer>, String> parsed = parseArgs(input);
       parsed.match(
           ok -> log.info("args were parsed successfully: {}", ok),
           err -> log.warn("The provided input could not be parsed: \"{}\"", err)
       );
       
      Parameters:
      ifOk - the lambda that is applied to the underlying data if the result is Ok.
      ifErr - the lambda that is applied to the underlying data if the result is an Err.
    • map

      <U> Result<U,E> map(Function<T,U> mapping)
      Apply a transformation to the wrapped value if the result is Ok. If the result is an Err, no transformation will be applied.
      
       assertEquals(
           6,
           Result.ok(5).map(x -> x + 1).unwrap()
       );
       assertEquals(
           "error",
           Result.<Integer, String>err("error").map(x -> x + 1).unwrapErr()
       );
       
      If an exception is thrown while applying mapping, the exception will not be caught. Ensure that any lambda passed to this function does not throw any runtime exceptions.
      Type Parameters:
      U - the type of the output of the transformation.
      Parameters:
      mapping - the transformation to apply to the wrapped value if the result is Ok.
      Returns:
      a new Result containing either the transformed value or the original error.
    • mapErr

      <F> Result<T,F> mapErr(Function<E,F> mapping)
      Apply a transformation to the wrapped value if the result is an Err. If the result is Ok, no transformation will be applied.
      
       assertEquals(
           "error: 'foo'",
            Result.err("foo").mapErr(err -> String.format("error: '%s'", err)).unwrapErr()
       );
       assertEquals(
           5,
           Result.ok(5).mapErr(err -> String.format("error: '%s'", err)).unwrap()
       );
       
      If an exception is thrown while applying mapping, the exception will not be caught. Ensure that any lambda passed to this function does not throw any runtime exceptions.
      Type Parameters:
      F - the type of the output of the transformation.
      Parameters:
      mapping - the transformation to apply to the wrapped value if the result is an Err.
      Returns:
      a new Result containing either the transformed error or the original value.
    • and

      <U> Result<U,E> and(Result<U,E> result)
      Returns the provided argument if the result is Ok and propagates the original Err otherwise.
      
       assertEquals(
           Result.err("first error"),
           Result.err("first error").and(Result.err("second error"))
       );
       assertEquals(
           Result.err("second error"),
           Result.ok(1).and(Result.err("second error"))
       );
       assertEquals(
           Result.ok(2),
           Result.ok("success").and(Result.ok(2))
       );
       
      Type Parameters:
      U - the type of the Ok value in the new result.
      Parameters:
      result - the value to be returned if the result is Ok.
      Returns:
      either the original error or the caller-provided Result.
    • andThen

      <U> Result<U,E> andThen(Function<T,Result<U,E>> resultFn)
      Apply a fallible operation to the wrapped value if the result is Ok. If the result is an Err, the error is propagated to the next operation in the chain.

      This operation differs from map in that if the value yielded by the provided fallible operation is an error, it is returned without being wrapped in a redundant, enclosing Result. Take, for example, two functions: getUserInput() which returns a Result<String, RuntimeException> and parseInt(String s) which returns a Result<Integer, NumberFormatException>. A chain of operations could be built up as follows:

      
       Result<Integer, RuntimeException> result = getUserInput().andThen(parseInt);
       
      If map had been used instead, the chain would have looked like:
      
       Result<Result<Integer, NumberFormatException>, NoSuchElementException> result = getUserInput().map(parseInt);
       
      Type Parameters:
      U - the output type of resultFn.
      Parameters:
      resultFn - the function to be applied if the result is Ok.
      Returns:
      either the output of resultFn or the original error.
    • or

      <F> Result<T,F> or(Result<T,F> result)
      Returns the provided argument if the result is an Err and propagates the original Ok value otherwise.
      
       assertEquals(
           Result.ok("success"),
           Result.err("error").or(Result.ok("success"))
       );
       assertEquals(
           Result.ok("first"),
           Result.ok("first").or(Result.ok("second"))
       );
       assertEquals(
           Result.err("second"),
           Result.err("first").or(Result.err("second"))
       );
       
      Type Parameters:
      F - the type of the Err value in the new result.
      Parameters:
      result - the value to be returned if the result is an Err.
      Returns:
      either the original value or the caller-provided Result.
    • orElse

      <F> Result<T,F> orElse(Function<E,Result<T,F>> resultFn)
      Apply a fallible operation to the wrapped value if the result is an Err. If the result is Ok, the value is propagated to the next operation in the chain.
      
       assertEquals(
           Result.ok("recovered from err: foo"),
           Result.err("foo").orElse(err -> Result.ok("recovered from err: " + err))
       );
       assertEquals(
           Result.ok("no error"),
           Result.ok("no error").orElse(err -> Result.ok("recovered from err: " + err))
       );
       
      Type Parameters:
      F - the type of the Err value in the new result.
      Parameters:
      resultFn - the function to be applied if the result is an Err.
      Returns:
      either the output of resultFn or the original value.
    • tryOr

      static <T, E extends Throwable> Result<T,E> tryOr(CheckedSupplier<T,E> supplier, Class<E> cls)
      Attempts to execute a fallible operation and returns any exceptions thrown during execution as the error type.
      Type Parameters:
      T - The type of the result value if no exception is thrown.
      E - The type of the result value if an exception is thrown by the provided function/
      Parameters:
      supplier - A lambda that will be evaluated at runtime to either yield a result or throw an exception
      cls - The class than the exception will be cast to if thrown. This is required because java cannot be generic over exceptions. If the caught exception cannot be case to this class, a runtime exception will be thrown.
      Returns:
      either the output of the provided supplier or a caught exception that was thrown during its evaluation.
      Throws:
      ErrorTypeMismatchException - if a caught exception cannot be cast to cls.