Simulator (and possibly devices) unexpectedly getting 0 response code passed to makeWebRequest callback
o The Environment:
Windows 10
Eclipse Neon.2 (4.6.2)
ConnectIQ 2.2.3
o A detailed description of the issue
The documentation mentions that responseCode parameter will be the server response code or one of the BLE_* error values. In some instances, I'm seeing the error code returned by the server is not making its way to the application. Instead the value Comm.UNKNOWN_ERROR is coming through.
o Steps to reproduce the issue
Run the python server code, then build and run the test case below. You will need to click the simulated device screen or the start button to trigger the first web request.
o Any applicable additional information
The application will test all possible HTTP codes from 100 to 599 inclusive. There are some cases where it may make sense to get an error code that is not the same as the server response code, but the few that are showing this unusual behavior don't seem like they should need to. In my testing, the following codes are not being passed through to the application.
204 No Content
304 Not Modified
416 Range Not Satisfiable
o A code sample that can reproduce the issue (in email only if preferred)
Here is a simple JSON-based web server that responds with an error code provided with the client request.
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()
This is the client code..
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() ];
}
}
Travis