string_viewoperator+ vs. StrCat()absl::Statusstd::bindabsl::optional and std::unique_ptrabsl::StrFormat()make_unique and private Constructors.boolexplicit= delete)switch Statements Responsibly= deleteAbslHashValue and Youcontains()std::optional parametersif and switch statements with initializersinline Variablesstd::unique_ptr Must Be MovedAbslStringify()vector.at()auto for Variable Declarationsabsl::StatusOriginally posted as TotW #76 on May 4, 2014
Updated 2020-02-06
Quicklink: abseil.io/tips/76
Some folks have questions about when and how to use absl::Status, so here are
a few reasons why you ought to use Status, and some things to keep in mind
when using it.
Use Status to force the caller to handle the possibility of errors. Since June
2013, a function returning an Status object cannot simply be ignored. That is,
this code produces a compilation error:
absl::Status Foo();
void CallFoo1() {
Foo();
}
Whereas these calls are fine:
void CallFoo2() {
Foo().IgnoreError();
}
void CallFoo3() {
if (!status.ok()) std::abort();
}
void CallFoo4() {
absl::Status status = Foo();
if (!status.ok()) LOG(ERROR) << status;
}
Why is it OK for Status to have an IgnoreError() method, while we just went
through all this effort to make the compiler check that Status isn’t ignored?
Imagine you’re the code reviewer looking at either CallFoo1() or CallFoo2().
The latter code snippets make the reviewer think “This function could have had
an error, but the author thinks its OK to ignore it. Is it?” CallFoo1() does
not trigger such a response.
Use Status when it’s not clear in your code how to handle the error. Instead,
return a Status, and let the caller, who may have more appropriate insight,
handle the error.
For example, logging locally might impact performance, such as when writing
infrastructure code. If your code is called in a tight loop, even a call to
LOG(INFO) may be too expensive. In other cases, users may not really care if a
call succeeds, and find the log spam intrusive.
Logging is appropriate in many cases, but functions that return Status don’t
need to LOG to explain why something failed: they can return the failure code
and error string and let the caller decide what the right error handling
response should be.
The Google style guide famously prohibits exceptions (it’s discussed more than
any other prohibition). It can be tempting to view absl::Status as a poor-
man’s exception mechanism, with a lot more overhead. While there may be
similarities on the surface, absl::Status differs in its need to be explicitly
handled, rather than just passed up the stack invisibly as an unhandled
exception. It forces engineers to decide how to handle errors, and explicitly
documents that in compilable code. And finally, returning an error using a
absl::Status is orders of magnitude faster than throwing and catching an
exception. These features may seem onerous when writing code, but the result is
a net win for everyone that has to read that code, and for Google as a whole.
Error handling is one of the easiest things to get wrong: these are inherently
the edge cases. A utility like Status that adds consistency to error handling
across API boundaries, projects, processes, and languages helps us minimize a
large class of “There were issues with our error handling” bugs. If you’re
designing an interface that needs to express the possibility of failure, please
use Status if you don’t have a pretty strong reason to do otherwise.