[PATCH] D105014: added some example code for llvm::Expected<T>

Sam McCall via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 13 05:19:36 PDT 2021


sammccall added a comment.

In D105014#2872674 <https://reviews.llvm.org/D105014#2872674>, @dblaikie wrote:

> + at lhames for context as the author/owner of `llvm::Error` and associated things.
>
> Perhaps it'd be handy to have some descriptions of the problems you encountered, @kuhnel, and how you went about trying to resolve them, to help understand where things are lacking.
>
>> @sammccall 
>> I agree Error is confusing and better docs might help.
>> (Not as much as removing the confusing part of the design, but I that seems hard at this point!)
>
> Maybe in this review, or maybe elsewhere: might be good to have some details on your perspective here?

Mostly that the attempt to enforce handling is an interesting idea but a cure worse than the disease in practice. In interacting closely with ~6 developers over the last ~4 years:

- most people were initially confused by this class and took significant time to build up a mental model, and are still fuzzy (e.g. on how it interacts with move semantics). I think this was Christian's experience here.
- In practice, developers who know Error well still sometimes check in code with "unhandled" errors by mistake
- most such code is correct except for the enforcement itself. e.g. test code that's missing a `cantFail(...)`, production code missing a `consumeError(Exp.takeError())` after handling failure.
- In practice, these mistake are difficult for reviewers who know Error well to catch
- it causes the Error class to have interface warts (`toString()` consumes the move-only object, operator== is non-const) that cause surprising ergonomic problems, e.g. requiring special helpers when used from test code

We've talked about the possibility of adding separate Error/Expected types to clangd with similar semantics but no check-enforcement and a simpler payload model. However having to deal with both error types seems too painful.

There's one case that's problematic enough to cause real danger, and has bitten us a couple of times:

- an `Expected<T>` is obtained and checked for success
- dynamically the value is almost always OK (e.g. except when out of disk space)
- in the failure case, the error is handled but not consumed. This is not caught in tests because the error condition is hard to simulated
- now months later when the error occurs in the wild in a debug build (yes, people seem to use these...) it becomes a crash

---

Separately from this issue, creating/logging errors is pretty clunky in the common case, and error handling is ubiquitous.
I wonder if there's appetite for the `error()` function from `clang-tools-extra/clangd/support/Logger.h` to live somewhere common.
(Both `error()` and the support for errors in `log()` in that file are pretty useful quality-of-life features, but `log()` is maybe not well-suited for llvm)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105014/new/

https://reviews.llvm.org/D105014



More information about the llvm-commits mailing list