After some investigation this is an approach I've found...
In my python code:
raise HTTP(409, "Team name already exists.", exception="team-name-not-unique", name=name, cap=cap)
The 400 codes are for client errors and 409 is a "CONFLICT" (e.g., a conflict for a resource - in my case for an attempt to name a team the same as another team; cap is just included to illustrate multiple parameters).
The named parameters (name & cap) are added to the response's headers.
In GWT create an exception class TeamNameNotUniqueException.java based on Exception with a CONST to take a name & cap and a getName() & getCap() methods.
In the onResponseReceived() of RequestBuilder you can check response.getStatusCode() == Response.SC_CONFLICT
String type = response.getHeader("exception");
if (type.equals("team-name-not-unique")) {
asyncCallback.onFailure(new TeamNameNotUniqueException(response.getHeader("name"),
Integer.parseInt(response.getHeader("cap"))));
Put all this in a try/catch block to handle errors and so we can otherwise assume the headers are correct.
One can add on additional tests again "type" for using alternative exceptions.
Downsides:
- this approach does place all such exception classes into one file which doesn't keep code splitting streamlined. At least the exception classes are small.
- the file has to be edited each time a new exception class is required by an app.