makeWebRequest ResponseCode == 0 when it should be 4xx

I'm making requests to a proprietary HTTP server which is returning error codes to the responseCallback method.

When the request fails for whatever reason (server offline, phone isn't connected, etc.) I get the expected error codes (e.g. 400, 404, etc.)
When the request succeeds, I get the expected 200 response code.
However, when the request is handled, but a the server returns an error, the callback receives a response code of "0".

I've used curl to test the server and this returns the expected error code (418 - "I'm a teapot")

Any ideas?
Thanks,
Oliver
  • First off, a responseCode value of 0 is documented as Comm.UNKNOWN_ERROR. I'm not sure why you'd be getting an error for an otherwise legal response code. Are you sure that your server is returning a valid response that the framework can understand? i.e., is the response body json, fit, or gpx data, and does it include headers to help the system figure out how to handle that data (or does your request set the appropriate options)?

    I wrote up a python test server that will respond with a HTTP error code of the client's choosing...

    import BaseHTTPServer
    import json
    
    class MockJsonRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    
    def init(self):
       pass
    
    # given a path /<digits> return a response with <digits> as the response
    # code and a json body with that same data
    def do_GET(self):
       try:
          paths = self.path.split('/')
          code = int(paths[1])
       except:
          code = 400
    
       self.send_response(code)
       self.send_header("Content-Type", "application/json")
       self.end_headers()
       self.wfile.write(json.dumps({ "code": code }))
    
    
    def _main():
       server_address = ('', 8000)
    
       httpd = BaseHTTPServer.HTTPServer(server_address, MockJsonRequestHandler)
       httpd.serve_forever()
    
    
    if __name__=='__main__':
       _main()



    I then wrote a MonkeyC client to make requests for every status code from 100 to 599 inclusive...

    using Toybox.Application as App;
    using Toybox.Lang as Lang;
    using Toybox.System as Sys;
    using Toybox.WatchUi as Ui;
    using Toybox.Graphics as Gfx;
    using Toybox.Communications as Comm;
    
    class XResponseDelegate
    {
        hidden var _M_url;
    
        function initialize(url) {
            _M_url = url;
        }
    
        hidden var _M_callback;
    
        function makeWebRequest(url, params, options, callback) {
            _M_callback = callback;
    
            Comm.makeWebRequest(url, params, options, method(:onWebResponse));
        }
    
        function onWebResponse(code, data) {
            _M_callback.invoke(code, data, _M_url);
        }
    }
    
    class XBehaviorDelegate extends Ui.BehaviorDelegate
    {
        hidden var _M_code;
    
        function initialize() {
            BehaviorDelegate.initialize();
        }
    
        function fetchResponse(code) {
            var url = Lang.format("localhost:8000/$1$", [ code ]);
    
            var params = {
            };
    
            var options = {
            };
    
            var delegate = new XResponseDelegate(url);
            delegate.makeWebRequest(url, params, options, method(:onWebResponse));
        }
    
        function onSelect() {
    
            if (_M_code == null) {
                _M_code = 100;
                fetchResponse(_M_code);
            }
    
            return true;
        }
    
        function onWebResponse(code, data, url) {
            Sys.println(Lang.format("$1$ returned $2$", [ url, code ]));
    
            if (_M_code < 599) {
                ++_M_code;
                fetchResponse(_M_code);
            }
            else {
                _M_code = null;
            }
        }
    }
    
    class XView extends Ui.View
    {
        function initialize() {
            View.initialize();
        }
    
        function onUpdate(dc) {
            dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
            dc.clear();
        }
    }
    
    class XApp extends App.AppBase
    {
        function initialize() {
            AppBase.initialize();
        }
    
        function getInitialView() {
            return [ new XView(), new XBehaviorDelegate() ];
        }
    }
    



    I ran that, processed the output, and found that a few values were being handled as you suggest...

    http://localhost:8000/100 returned 100
    ...
    http://localhost:8000/203 returned 203
    http://localhost:8000/204 returned 0
    http://localhost:8000/205 returned 205
    ...
    http://localhost:8000/303 returned 303
    http://localhost:8000/304 returned 0
    http://localhost:8000/305 returned 305
    ...
    http://localhost:8000/415 returned 415
    http://localhost:8000/416 returned 0
    http://localhost:8000/417 returned 417
    ...
    http://localhost:8000/599 returned 599


    I looked at the server output and it clearly indicates that it sent the correct responses. I looked at the http code mappings, and and the affected codes are

    • 204 No Content
    • 304 Not Modified
    • 416 Range Not Satisfiable



    I'm not sure why these codes would not make it to the application, so that does seem like a bug of some sort. I can understand the application (simulator or Garmin Connect Mobile) eating some responses (301 and 302 can't be handled by a ConnectIQ application unless the HTTP headers are passed through) and returning error codes, but these error codes should not belong to that set.

    Perhaps one of the Garmin guys with access to the VM source can chime in?

    Travis

  • Former Member
    Former Member over 8 years ago
    I don't think the VM looks at these codes at all, so I am pretty sure Garmin Connect Mobile is the spot where things are getting tripped up. I would recommend creating an official bug report for this.
  • It should be noted that I did all of my testing in the simulator. I don't have the appropriate cables with me to test on a device.

    Travis
  • Former Member
    Former Member over 8 years ago
    Yeah, that probably should have been obvious. An official bug report would still be good to have. I don't know how the VM would be doing anything with these specific response codes, so I still think it is outside of there. Whatever the sim is using to make these requests for the VM must not be completing successfully it seems.
  • This has been filed in the official bug reports forum. I will close this thread for now. Please look for this issue there to keep updated.

    Thanks,
    -Coleman