Ok, I figured out what's going on here. Checked exceptions appear to be handled automatically by GWT and thrown to the client (not sure what happens here if they're not serializable).
Unchecked exceptions are processed by AbstractRemoteServiceServlet.doUnexpectedFailure(Throwable). There does not appear to be a way to register a global exception handler so a base class overriding this method was necessary. Additionally, this method defers to RPCServletUtils.writeResponseForUnexpectedFailure(...) to write the response to the server. This utility method essentially ignores the error thrown on the server and writes a generic response.
The solution was to override the method and rather than call the RPCServletUtils method, to copy and tweak it so that it sends back the message I need to send.