4

I've been learning Google Endpoints from the tutorial at https://developers.google.com/appengine/docs/java/endpoints/. I got the Endpoint successfully deployed to Google App Engine and I managed to build a simple iPhone app that calls the Endpoint. However, my iPhone app gets the following error when it tries to call the Endpoint:

Error Message

error NSError * domain: @"com.google.GTLJSONRPCErrorDomain" - code: -32099 0x00000001094518a0

_userInfo __NSDictionaryI * 3 key/value pairs 0x00000001094452b0

[0] (null) @"error" : @"java.lang.IndexOutOfBoundsException: Index: 0, Size: 0"
[1] (null) @"NSLocalizedFailureReason" : @"(java.lang.IndexOutOfBoundsException: Index: 0, Size: 0)"
[2] (null) @"GTLStructuredError" : (no summary)

iPhone API Caller (in Objective-C running in Xcode Debugger)

- (IBAction)myButton:(id)sender {
    NSInteger myId;
    if (self.mySwitch.isOn) {
        myId = 0;
    }
    else {
        myId = 1;
    }
    GTLQueryHelloworld *query = [GTLQueryHelloworld queryForGreetingsGetGreetingWithIdentifier:myId];
    [self.helloWorldService executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
        if (!error) {
            [self.myLabel setText:object];
        }
        else {
            [self.myLabel setText:[error description]];  // This line gets called 
        }
    }];
}

I found the same error message reported in Youtube video upload fails after 100 % progress for some users with Backend Error code:-32099 but that pertained to calling YouTube and it was eventually closed as a bug that was fixed. So I don't think it's related.

I believe the bug is on the client side because I put some logging on the server (Java) and it does not appear to get called:

public class Greetings {
    private static final Logger log = Logger.getLogger(Greetings.class.getName());

    public static ArrayList<HelloGreeting> greetings = new ArrayList<HelloGreeting>();

    static {
            log.setLevel(Level.INFO);
            greetings.add(new HelloGreeting("hello world!"));
            greetings.add(new HelloGreeting("goodbye world!"));
    }

        public HelloGreeting getGreeting(@Named("id") Integer id) {
            log.info("HelloGreeting called with getGreeting");
            log.info("getGreeting id " + id);
            return greetings.get(id);
    }

I don't see "HelloGreeting called with getGreeting" in my Google server logs, all I see is the log message indicating that my Endpoint project was successfully deployed:

21:56:45.639 Endpoints: https://1-war-dot-firstendpointproject.appspot.com/_ah/api/helloworld@v1 Saved

I've also confirmed I can successfully test the helloworld.greetings.getGreeting API from the deployed API explorer for my project:

https://1-war-dot-firstendpointproject.appspot.com/_ah/api/explorer

When I call the API from the Explorer it generates a log message:

24.130.150.54 - - [19/Jun/2014:21:17:45 -0700] "POST /_ah/spi/com.google.appengine.samples.helloendpoints.Greetings.getGreeting HTTP/1.1" 200 93 "https://1-war-dot-firstendpointproject.appspot.com/ah/api/static/proxy.html?jsh=m%3B%2F%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.htta44JhPmg.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Fz%3Dzcms%2Frs%3DAItRSTPk1CJ1YqUCyb-H-zhkQTjKPZwvbQ" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14" "1-war-dot-firstendpointproject.appspot.com" ms=17 cpu_ms=87 cpm_usd=0.000010 instance=00c61b117ce13f56d6eb483511c2c1bcd24241 app_engine_release=1.9.6

It does not generate "HelloGreeting called with getGreeting" but I suspect that is because I have not configured the logger. At any rate, when my client calls the Endpoint I get no log message at all. Since the API explorer call at least generates 1 log message, I suspect the problem is on the client.

Questions:

1] Is the error I'm seeing generated on the client or the server side?

2] Do you know what array this error is refering to?

3] What are some techniques for debugging a connection problem like this?

Thanks for your help StackOverflowers!

Michael

Community
  • 1
  • 1
Michael Osofsky
  • 11,429
  • 16
  • 68
  • 113
  • 1
    +1 for I am running into the same problem (`Error Domain=com.google.GTLJSONRPCErrorDomain Code=-32099` when calling from Objective C against my Google Cloud Endpoints service) and would love to see an answer ... – Drux Jun 21 '14 at 17:10
  • I've opened a support ticket with Google Cloud Support. So far they've helped by pointing out the problem must be in the Java code of the endpoint because the detailed error is a Java exception (java.lang.IndexOutOfBoundsException). Thanks for posting Drux, I'll let them know I'm not the only one. – Michael Osofsky Jun 21 '14 at 17:27

2 Answers2

3

I think what's going on is as the following: The server runs into an unexpected situation (specifically: it throws an unhanded IndexOutOfBoundsException), hence it cannot return the kind of JSON that the generated client stub expects in its HTTP response (specifically: it returns HTTP status 500 instead of 2xx). The client stub reports this as NSError with domain com.google.GTLJSONRPCErrorDomain and code 32099. The JSON-RPC 2.0 spec defines this error code as "reserved for implementation-defined server-errors".

It would seem that the best way to handle this is add appropriate exception handling either on the server- or client-side, depending on what exactly caused the unexpected situation on the server. An IndexOutOfBoundsException is most likely for the server to handle, as it may stem from an application-level bug.

So to answer the verbatim question: the (original) error is on the server. BTW, unlike the OP I do see related JUL logging output in the Google Developers Console.

Drux
  • 11,992
  • 13
  • 66
  • 116
  • Congrats @Drux on getting that far. As far as I can tell, not only is my logging not outputting in the Google Developers Console but also the code does not even seem to be running. I simplified it down so all it does is `new HelloGreeting("holamundo")`. That also returns `java.lang.IndexOutOfBoundsException`. So I'm wondering if it's throwing the exception on the Endpoint code that's called before my getGreeting method is called. – Michael Osofsky Jun 22 '14 at 01:30
  • @MichaelOsofsky have you tried adding `try`/`catch` and setting a breakpoint in the debugger in your servlet's `@ApiMethod` code to double-check? Could it be that you updated `@ApiMethod`s without running `ServiceGenerator`, etc., again? BTW, mine is a `JsonMappingException`, not `IndexOutOfBoundsException`, so the situations are slightly different. – Drux Jun 22 '14 at 06:18
  • Thanks @Drux, I've now added a try/catch(Exception e) block on my Endpoint. The catch block doesn't get called. The error seems to happen before my Endpoint application code is actually reached. – Michael Osofsky Jun 22 '14 at 16:52
  • I've got more evidence the error is generated by the server. I turned off my wireless and then ran the iPhone app in the Xcode debugger. When I clicked the button that initiates the Endpoint call I got a different error: [0] (null) @"NSUnderlyingError" : (no summary) [1] (null) @"NSErrorFailingURLStringKey" : @"https://helloendpoints.appspot.com/_ah/api/rpc?prettyPrint=false" [2] (null) @"NSErrorFailingURLKey" : @"https://helloendpoints.appspot.com/_ah/api/rpc?prettyPrint=false" [3] (null) @"NSLocalizedDescription" : @"The Internet connection appears to be offline." – Michael Osofsky Jun 24 '14 at 15:05
  • @MichaelOsofsky yes, it must be the server. I guess something prevents it from parsing or generating the JSON that is described by the API method signatures. That's why I thought that the descriptions used by the client and server could be out of sync. BTW, I've been able to get rid of error 32099 in my case by fixing the root cause in my application/service code. – Drux Jun 24 '14 at 19:27
  • Thank you, I'm happy for you. In my case I have virtually no application logic. I've got a support case open with Google and they asked for my whole project which is on DropBox and I can share that with anyone who wants the bounty. – Michael Osofsky Jun 24 '14 at 22:57
1

I looked at your endpoint and successfully called it in the explorer and with curl. I am pretty sure that the problem is in the client and the server doesn't understand the request.

If you are sure you are calling the client correctly, I would try regenerating it. Perhaps there has been a bugfix since the last time you generated.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192