]> granicus.if.org Git - llvm/commit
[Error] Add a handleExpected utility.
authorLang Hames <lhames@gmail.com>
Mon, 28 Aug 2017 03:36:46 +0000 (03:36 +0000)
committerLang Hames <lhames@gmail.com>
Mon, 28 Aug 2017 03:36:46 +0000 (03:36 +0000)
commit68a7b2d85a2ba3c7a97587415474046129ab5605
tree36aa320b19793288f2da9903bc4461566c0bcbbd
parent3607b8f0f2d44de8d397f745574ce398856db177
[Error] Add a handleExpected utility.

handleExpected is similar to handleErrors, but takes an Expected<T> as its first
input value and a fallback functor as its second, followed by an arbitary list
of error handlers (equivalent to the handler list of handleErrors). If the first
input value is a success value then it is returned from handleErrors
unmodified. Otherwise the contained error(s) are passed to handleErrors, along
with the handlers. If handleErrors returns success (indicating that all errors
have been handled) then handleExpected runs the fallback functor and returns its
result. If handleErrors returns a failure value then the failure value is
returned and the fallback functor is never run.

This simplifies the process of re-trying operations that return Expected values.
Without this utility such retry logic is cumbersome as the internal Error must
be explicitly extracted from the Expected value, inspected to see if its
handleable and then consumed:

enum FooStrategy { Aggressive, Conservative };
Expected<Foo> tryFoo(FooStrategy S);

Expected<Foo> Result;
(void)!!Result; // "Check" Result so that it can be safely overwritten.
if (auto ValOrErr = tryFoo(Aggressive))
  Result = std::move(ValOrErr);
else {
  auto Err = ValOrErr.takeError();
  if (Err.isA<HandleableError>()) {
    consumeError(std::move(Err));
    Result = tryFoo(Conservative);
  } else
    return std::move(Err);
}

with handleExpected, this can be re-written as:

auto Result =
  handleExpected(
    tryFoo(Aggressive),
    []() { return tryFoo(Conservative); },
    [](HandleableError&) { /* discard to handle */ });

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311870 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Support/Error.h
unittests/Support/ErrorTest.cpp