Errors and the introspection format
dbus at matthew.ath.cx
Sat Feb 18 09:11:50 PST 2006
On Sat, 18 Feb 2006, Havoc Pennington wrote:
> On Sat, 2006-02-18 at 10:44 +0000, Matthew Johnson wrote:
>> DBus has a great self-documenting system for the APIs, if you include
>> exceptions and possibly a short description, it would be *really*
>> *really* good, and contain everything I can think that I would like to
>> know. With the aid of the XSLT I posted to the list a couple of days ago
>> you can even generate nice javadoc-like webpages from it.
> Including exceptions in the docs (like javadoc @throws) I have no
> problem with. What I think is a mistake (for dbus) is putting them in
> the method signature and using them to generate per-method code. That
> creates a whole school of issues and "ABI breaks" that only one binding
> can have, and changes how you do API design (e.g. I think the HAL Lock()
> API from the old thread is kind of a bad pattern in
> non-checked-exception languages, I might go with return codes or
> something instead)
Given you have support for returning errors I think you should use them
rather than just return codes, it makes it nicer in some cases, and no
worse in others. As David said it's an API break to change the
exceptions you throw as much as it is to change the parameters you take
and this breaks people who compare strings as much as it breaks things
which compare strings.
Also, you aren't 'linking' to the thing at the other end. If the method
signature doesn't match it doesn't actually matter as long as you send
acceptable things on the wire. Changing the checked exceptions which are
listed will just mean that either something you have listed never gets
thrown, or you get an unchecked exception thrown that you weren't
expecting. This is the same as if you were comparing strings and it
returns an unexpected string---it just drops out to the default case
> I think it might be fine to have some kind of global list of exceptions,
> and generate the exception classes in Java. Then you can write nice
> try/catch code. I just don't think you should generate the throws
> clauses on methods. For a global list of exceptions, the main question
> would be where in the introspection data to put them though.
Yes, this is a perfectly sensible approach. This is why I'm suggesting
annotations rather than <throws> tags. An <exception> tag at the same
level as <interface> might be nice if exceptions need to have
properties. If they only have a single string message then I can create
them straight from the annotation.
> I thought you said you were making DBusException unchecked anyway? It's
> certainly not typical to have throws clauses for unchecked exceptions,
> only javadoc @throws at most.
putting in explicit throws allows me to put them back in the
introspection data as annotations, I could just leave them as
annotations permanently, but I thought I'd use the language feature
while I had it. Currently DBusExecutionException is unchecked and
everything thrown from a method descends from that, I might consider
making explicitly declared ones checked. This is a binding-specific
>> and I do believe
>> that it will benefit all programmers of clients due to having them
>> written down at the top of the function.
> You're saying it would be good _if_ the information was up-to-date and
> accurate. Let's concede that for a moment.
> I'm saying it won't be, because only Java programmers will care. If I'm
> writing a dbus object in Python, I'm not going to get the exception info
> right. Also, having checked exceptions vs. not changes how you want to
> do API design.
Certainly as it is, no-one else includes error information. If you say
'you should include it like this' then people are much more likely to.
I'd like to consider it a bug as much as not listing them correctly in
the docs would be. How does it affect the API design on the server if
clients are using checked exceptions or not? What should affect it is
whether you have exception support. Were DBus not to have error support
then people would use return codes. Given it does (which I think is a
good thing) they should use errors.
> The "DBusException" approach is the norm in Java server-side programming
> at least anyway; EJBException, JMSException, HibernateException,
> SQLException, people always just have one generic exception for the
> whole module. It's not like this is some kind of Java heresy.
Well, IOException has got it right, I feel. You can just catch
IOException if you want, but you can also catch FileNotFoundException if
you want to go and do something about it and so on. This is what I'd
like to see---normally a dbus failure will just propogate up to some
general handler, but when things have an error condition which we
consider less fatal you can deal with it in a nice way.
> But again we can do one better, you could define classes for a bunch of
> DBusException subclasses (including at least the standard exceptions,
> and if we can think of a way then also module-specific ones).
> I would probably do DBusException, and then group a couple categories of
> the standard exceptions with base classes, like:
> class DBusException extends RuntimeException;
> class DBusCommunicationException extends DBusException;
> class DBusIOError extends DBusCommunicationException;
> class DBusNoNetwork extends DBusCommunicationException;
What I'm trying to do is to make the Java FQCN be the same as the DBus
name for as much as possible, so if you want to implement the interface
"org.freedesktop.Foo" you create an interface of that name, similarly
for exceptions you create an exception of that name.
Essentially I don't really mind _how_ they are listed in the
introspection data, I just think they _should_ be. If there is an
official method then at least it will happen some of the time! Since
everyone is expected to propogate annotations then I think this is a
sensible way to do so (I suggest org.freedesktop.DBus.Method.Error). If
someone writing in python notices the annotation at the top of their
method and remembers to catch it, then this is a nice bonus.
More information about the dbus