[Cosmo-dev] Client Side Service Exceptions
Bobby Rullo
br at osafoundation.org
Tue Feb 6 18:05:40 PST 2007
For bug 7572 - "handle CollectionLockedException in Cosmo UI" - I had
to add some client side Exceptions. After grepping through all the
code, it turns out we're not doing much with these exceptions (those
that are mapped from Java ones) - which is largely a function of the
mappings being wrong (they were still mapped from Scooby exceptions
which obviously don't exist anymore.) Therefore I am taking this
opportunity to talk about how to deal with service exceptions in the
Cosmo UI.
1) Exceptions that are thrown from RPC calls on the server can be
mapped to JavaScript Exceptions on the client. Obviously not all
possible Java exceptions are mapped to JavaScript exceptions - those
just become generic JavaScript Errors. Right now the only two Java
exceptions that are mapped are the ConcurrencyFailureException and
CollectionLockedException. They are both mapped to
"cosmo.service.exception.ConcurrencyException". All service code
should be wrapped in a try catch block. To watch out for a specific
exception you do something like the following:
Synchronous Example:
try {
Cal.serv.saveEvent(cid, event);
} catch (e if e instanceof
cosmo.service.exception.ConcurrencyException) {
showMessage("Someone else is modifying your event!");
} catch (e) {
//handle other errors that might happen on the server
showMessage("Something bad happened.");
}
Asyncrhonous Example:
callback = function(returnObject, error){
if (error){
if (error instanceof
cosmo.service.exception.ConcurrencyException){
showMessage("Someone else is modifying your event!");
} else {
showMessage("Something bad happened");
}
}
}
Cal.serv.saveEvent(callback, cid, event);
Notice the use of the "instanceof" operator to determine the
exception type, and therefore how to handle the error. Also notice
the conditional catch clause in the synchronous example - a neat JS
feature I didn't know existed. If none of the conditional catches
match the exception, the last "catch-all" catch will catch the
exception.
2) For this specific bug (7572) I don't recommend the ui code merely
re-trying to update the event. This would blow away any changes that
we're just made by the other client. Not sure what a better solution
is though short of a whole conflict resolution ui. Maybe a dialog box
like "Keep your changes, or get changes from the server?"
Also mde mentions the need of a "This item was deleted by someone
else while you were trying to edit it, so it's gone now." sort of
Exception. The problem is I don't think the server can tell whether
an item is not around anymore because it was deleted, or because it
never existed - it just knows that there is no such item with a UID
of xxxxxxx. The proper thing to do would be to throw a
"NoSuchResource" exception and catch that and have the client
interpret it in the proper way ("The item in question no longer
exists...Do you want to blah blah blah" or something). This is not
implemented yet however, so you'll just get some weird error from the
server.
3) Don't rely on the stuff inside error objects for anything. Sure, I
didn't have to do all this wrapping - we could've just looked for
"org.spring.dao.ConcurrencyException" whenever we called a service
method, but then you'd have dependencies on Spring all over the place
in your JavaScript code. And then you'd have to get rid of them all
once we move to our GData solution.
Once we have the GData solution in place, we can still use these
Exceptions - instead creating them by mapping Java Exceptions though
we have our client side service layer map them to GData error codes,
or Http error codes or however it will work. Yay.
4) Similarly, I think it's a bad idea to have the error dialog
display error messages from the server or from the exception object
itself in general. Better to figure out what the exception is, and
dig up a user-friendly message from the i18n file. If it's not an
exception that we have mapped, default to displaying a generic
"There's been a problem with the server"
5) Let's create more exceptions! If there are others that need to be
mapped that we need to handle specially let me know.
Right now this code is checked into my own branch (I got impatient.)
I'll merge it tomorrow. For the moment you can look at commit r3607
Bobby
More information about the cosmo-dev
mailing list