Change record status: 
Project: 
Introduced in branch: 
11.x
Description: 

Drupal has introduced the Drupal\Core\Result type that can be used to indicate success or failure. This can be used in case an operation can succeed or fail but throwing an exception not appropriate. For example in a list of tasks where individual tasks fail without stopping the processing of other tasks in the list (for example parallel render tasks using PHP Fibers). In such a case throwing an exception would cause PHP to aboard the entire list of tasks.

The value contained in the result can depend on whether the result is in the success or error state. PHPStan generic annotations can be used to indicate the type of the value contained in the result in the success and error cases.

Writing a function that returns a result
Writing a function that returns a string on success or an exception on failure could be done as follows:

declare(strict_types=1);

use Drupal\Core\Result;

/**
 * Randomly decides between success and failure.
 * 
 * @return \Drupal\Core\Result<string, \Exception>
 *   A result that contains a string on success or that contains an exception on error.
 */
function flip_coin() : Result {
  if (random_int(0,1) === 0) {
    return Result::ok("You've landed on heads!");
  }
  return Result::error(new \RuntimeException("Oops, you've hit tails"));
}

Writing a function that accepts a result as argument
You can also write a function that uses the result. For example in case you want to perform an action on success but propagate the error on failure. Taking the coin flip above as example lets share the answer to everything in case it came up heads.

declare(strict_types=1);

use Drupal\Core\Result;

/**
 * Reveal the universe on a successful result.
 *
 * @param \Drupal\Core\Result<string, \Exception>
 *   The result from flip_coin.
 *
 * @return \Drupal\Core\Result<int, \Exception>
 *   The answer to the universe in case the input result was ok or the propagated error otherwise.
function reveal_universe(Result $result) : Result {
  if ($result->isOk()) {
    return Result::ok(42);
  }
  return $result;
}
Impacts: 
Module developers