<div dir="ltr"><div>I completely agree that for errors returned by the service, a D-Bus error is a lot better. However, from what I understand of sd-bus, any errors returned by the service are encoded in the reply returned by sd_bus_call and you use sd_bus_message_is_method_error and sd_bus_message_get_error on the reply to get the actual service error. Where does that leave the sd_bus_error argument of sd_bus_call? Is it simply another way to get the error? It seems to be always be set when a local or remote error occurs, but it can only contain information that I can get by checking the return value of the function or by checking whether the reply object passed to sd_bus_call contains an error.</div><div><br></div><div>How I would imagine using sd_bus_call:</div><div><br></div><div>r = sd_bus_call(..., reply, ...);</div><div>if (r < 0) {</div><div>  // Local error<br></div><div>}</div><div><br></div><div>if (sd_bus_message_is_method_error(reply)) {</div><div>  const sd_bus_error *error = sd_bus_message_get_error(reply);<br></div><div>  // Service error<br></div><div>}</div><div><br></div><div>But if this is the intended usage, what's the use of the sd_bus_error argument of sd_bus_call since the above code already handles both the local error and the remote service error failure paths?<br></div><div><br></div><div>Daan<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 18 Mar 2020 at 11:57, Simon McVittie <<a href="mailto:smcv@collabora.com">smcv@collabora.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tue, 17 Mar 2020 at 20:17:05 +0100, Daan De Meyer wrote:<br>
> I'm documenting sd_bus_call and its async variant and I was wondering about the<br>
> sd_bus_error output parameter that's passed to it. [...] I don't<br>
> see immediately see the benefit of the sd_bus_error parameter in a D-Bus client<br>
> since I can simply check the return value instead which seems to contain the<br>
> same information looking at the implementation.<br>
<br>
The return value is a single int, which according to systemd conventions<br>
is probably a negative errno value. That's a lot less information than<br>
a D-Bus error (systemd sd_bus_error, libdbus DBusError or equivalent):<br>
D-Bus errors consist of a machine-readable name (namespaced by a reversed<br>
domain name) and a human-readable message.<br>
<br>
For the information about *whether* an error occurred, sure, you get the<br>
same information, but for information about *which* error occurred and why,<br>
a sd_bus_error is a lot better.<br>
<br>
Let's pretend your D-Bus client is interacting with a D-Bus service that<br>
resembles systemd-timedated. An errno value can give you, at best,<br>
something like this (where *** marks the part that came from the service's<br>
reply):<br>
<br>
    my-client: Error: Unable to set time zone to America/Gotham:<br>
    ***No such file or directory (errno 2)***<br>
<br>
whereas a D-Bus error (sd_bus_error) from a well-implemented service can<br>
give you something a lot more detailed. For example, after you ispect<br>
the sd_bus_error, you might find that the error above was either of these:<br>
<br>
    my-client: Error: Unable to set time zone to America/Gotham:<br>
    ***No time zone file for "America/Gotham" found (tried<br>
    "/usr/share/zoneinfo/America/Gotham",<br>
    "/usr/local/share/zoneinfo/America/Gotham")<br>
    (error code com.example.NotTimedated.Error.NoSuchTimezone)***<br>
<br>
    my-client: Error: Unable to set time zone to America/Gotham:<br>
    ***No time zone data installed (tried "/usr/share/zoneinfo",<br>
    "/usr/local/share/zoneinfo")<br>
    (error code com.example.NotTimedated.Error.TzdataNotInstalled)***<br>
<br>
In this example a programmatic client would also be able<br>
to respond differently to the distinct machine-readable<br>
errors com.example.NotTimedated.Error.NoSuchTimezone and<br>
com.example.NotTimedated.Error.TzdataNotInstalled if it wanted to;<br>
for example it could respond to the second error by trying to use<br>
PackageKit to install tzdata, which obviously wouldn't be appropriate<br>
for the first error.<br>
<br>
D-Bus errors were inspired by GLib's GError, which is basically a triple<br>
{ domain: interned string, code: int, message: string }, where the domain<br>
provides extensible uniqueness, and the code is a member of an enum<br>
determined by the domain.<br>
<br>
    smcv<br>
_______________________________________________<br>
systemd-devel mailing list<br>
<a href="mailto:systemd-devel@lists.freedesktop.org" target="_blank">systemd-devel@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/systemd-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/systemd-devel</a><br>
</blockquote></div>