TL;DR: fidl::UnbindInfo and result types in LLCPP have better logging support.
Action required: do not use .reason(), .status(), or .error_message() when logging LLCPP errors. See the better alternatives below.
When using the LLCPP FIDL bindings, you may have came across error logging code looking like the following:
or alternatively when making method calls:
It can be cumbersome manually logging all the relevant information, and different call-sites tend to miss various bits and pieces. fxrev.dev/525500 improves the situation by introducing one uniform logging format that is also more detailed. The logging format is supported on these types:
fidl::UnbindInfo: the description of why a server/client endpoint was unbound
fidl::Result: the return value of one-way and asynchronous two-way calls
fidl::WireResult<Method>: the return value of synchronous two-way calls
fidl::OwnedEncodedMessage<T>: the encoding result in persistence use cases
fidl::UnbindInfo can be piped to the stream-based logger directly:
To log the error portion of a result type, use the .error() accessor:
Other stream-based API (e.g. FAIL() from gtest, std::cerr) are also supported.
Use the .FormatDescription() method to get a std::string:
When an error happens, the rendered log would look along the following lines:
Another example for when a fidl::Client unbinds:
The FormatDescription function allocates a string on the heap. There may still be scenarios where a const char* error message is desired, such as in latency-sensitive applications or when the error needs to be passed through a C API without worrying about ownership of the error string. In those cases, you may use the .lossy_description() method on a result, which would return a const char* with static lifetime (i.e. stays alive throughout the duration of the program). The lossy description as the name suggests would find the closest error string on a best-effort basis, and may lose information.
Cheers,
Yifei