Handling authorization exception from server to client

48 views
Skip to first unread message

André Salvati

unread,
Oct 26, 2011, 7:03:02 AM10/26/11
to Google Web Toolkit
Hi,

I've been working with GWT 2.4 and trying to send an authorization
exception from server to client whitout success.

1) Server:

A - Raise ReportableException throught report() on my
ServiceLayerDecorator.

B – Send the following JSON to the client:

{"S":[false],"I":[{"F":true,"M":"Não
autorizado","X":"com.google.web.bindery.requestfactory.server.ReportableException"}]}

2) Client:

AbstractRequestContext doesn't enter on processPayload() → if
(response.getGeneralFailure() != null) because it doesn't find key
“F” (but “F” is there, isn't??)


What is wrong?

Is it the right way to treat this kind of exception?

Thank you.

Thomas Broyer

unread,
Oct 26, 2011, 9:15:39 AM10/26/11
to google-we...@googlegroups.com
"F" is present in "I", meaning one particular invocation (service method call) failed, not the whole "batch request" (well, actually, "S":[false] says the one and only invocation failed, then the object in "I" gives information about the failure).

FYI, the response format is defined by the com.google.web.bindery.requestfactory.shared.messages.ResponseMessage AutoBean.

André Salvati

unread,
Oct 27, 2011, 7:19:17 AM10/27/11
to Google Web Toolkit

So, wasn't it supposed to enter the code bellow on
AbstractRequestContext? Is not it a "general" failure?? Maybe this is
an issue with RequestFactory...

if (response.getGeneralFailure() != null) {
ServerFailureMessage failure = response.getGeneralFailure();
ServerFailure fail =
new ServerFailure(failure.getMessage(),
failure.getExceptionType(), failure
.getStackTrace(), failure.isFatal());

fail(receiver, fail);
return;

Thomas Broyer

unread,
Oct 27, 2011, 8:34:18 AM10/27/11
to google-we...@googlegroups.com
No, it's not a "general failure", it's only a failure for one invocation. Look at few lines down in AbstractRequestContext:

      Set<Throwable> causes = null;
      for (int i = 0, j = invocations.size(); i < j; i++) {
        try {
          if (response.getStatusCodes().get(i)) {
            invocations.get(i).onSuccess(response.getInvocationResults().get(i));
          } else {
            ServerFailureMessage failure = AutoBeanCodex.decode(
                MessageFactoryHolder.FACTORY, ServerFailureMessage.class,
                response.getInvocationResults().get(i)).as();
            invocations.get(i).onFail(
                new ServerFailure(failure.getMessage(),
                    failure.getExceptionType(), failure.getStackTrace(),
                    failure.isFatal()));
          }

response.getStatusCodes().get(i) reads from the "S" (in your case, returns 'false', for i==0), and response.getInvocationResults().get(i) reads from the "I" (in your case, a ServerFailureMessage).

To be crystal clear:
requestContext.myMethod(arguments).to(new Receiver<X>() {
    @Override
    public void onSuccess(X response) {
        // won't get here
    }
    @Override
    public void onFailure(ServerFailureMessage error) {
        // will get there: the myMethod invocation failed; its Receiver's onFailure is called
    }
});
requestContext.fire(new Receiver<Void>() {
    @Override
    public void onSuccess(Void response) {
        // will get there: the myMethod invocation failed, but the whole "batch" succeeded: the context could have had other invocations that succeeded
    }
});

André Salvati

unread,
Oct 28, 2011, 9:24:57 AM10/28/11
to google-we...@googlegroups.com
Ok Thomas, understood.

Thank you.
Reply all
Reply to author
Forward
0 new messages