Repository: learningequality/kolibri

Issue:
improve 'kolibri status' command error reporting

### Observed behavior

We've had some difficulty debugging some connectivity issues here: https://community.learningequality.org/t/after-upgrading-to-kolibri-v0-11-1-server-continues-to-disconnects-and-reconnects-clients/995/3

Running `kolibri status` reported

> server configuration error (9)
> 
> ![image](https://user-images.githubusercontent.com/2367265/52284179-c0ac9300-2918-11e9-88d7-64739e7363bb.png)

Under the hood, this is just raising `STATUS_SERVER_CONFIGURATION_ERROR` from

```python
    check_url = "http://{}:{}".format("127.0.0.1", listen_port)

    if conf.OPTIONS["Server"]["CHERRYPY_START"]:

        try:
            # Timeout is 3 seconds, we don't want the status command to be slow
            # TODO: Using 127.0.0.1 is a hardcode default from Kolibri, it could
            # be configurable
            # TODO: HTTP might not be the protocol if server has SSL
            response = requests.get(check_url, timeout=3)
        except (requests.exceptions.ReadTimeout,
                requests.exceptions.ConnectionError):
            raise NotRunning(STATUS_NOT_RESPONDING)
        except (requests.exceptions.RequestException):
            if os.path.isfile(STARTUP_LOCK):
                raise NotRunning(STATUS_STARTING_UP)  # Starting up
            raise NotRunning(STATUS_UNCLEAN_SHUTDOWN)

        if response.status_code == 404:
            raise NotRunning(STATUS_UNKNOWN_INSTANCE)  # Unknown HTTP server

        if response.status_code != 200:
            # Probably a mis-configured kolibri
            raise NotRunning(STATUS_SERVER_CONFIGURATION_ERROR)

        return pid, LISTEN_ADDRESS, listen_port  # Correct PID !
```


### Expected behavior

The `get status` should return more verbose information about the error that occurred, including the actual error code and the response.

### User-facing consequences

harder for us to help our users debug


### Context

0.11.1



Discussion:
@indirectlylit  Could this be a valid solution?
traceback module can't be used at this point as there's no error, so the traceback will be always the same. 
The response message seems to be the more valuable information.


```
@@ -339,6 +338,9 @@ def get_status():  # noqa: max-complexity=16
 
         if response.status_code != 200:
             # Probably a mis-configured kolibri
+            sys.stderr.write('---Debug information---\n')
+            sys.stderr.write(response.text)
+            sys.stderr.write('\n-----------------------\n')
             raise NotRunning(STATUS_SERVER_CONFIGURATION_ERROR)
```

that looks good to me

the only thing we should check is whether we're treating the output of `status` as machine-parseable text in any case. I seem to recall suggestions of that in the past, for example to communicate current port information to installers?
No, we are not, all these constants are being translated to human language:
 in kolibri/utils/cli.py
`server.STATUS_SERVER_CONFIGURATION_ERROR: 'Kolibri server configuration error'`
but that's a different problem. It happens the same with all the `STATUS` constants.
What kind of machine-parseable text are you thinking? a code?
> What kind of machine-parseable text are you thinking? a code?

At one point [we had discussed](https://github.com/learningequality/kolibri-installer-windows/issues/65) interrogating `status` to drive the windows GUI's port selection. It was a very similar conversation to the questions about `kolibri-server` knowing about kolibri's selected port.

Looks like instead it's checking the `server.pid` file??

https://github.com/learningequality/kolibri-installer-windows/pull/80/files#diff-03d5f197d7e34c30938a1baf6746d5daR48


yes, and `status` does the same thing, the output is human readable but it's easily machine parseable too.
@jredrejo would you might implementing this?

Resolving patch:
diff --git a/kolibri/utils/server.py b/kolibri/utils/server.py
--- a/kolibri/utils/server.py
+++ b/kolibri/utils/server.py
@@ -402,6 +402,9 @@ def get_status():  # noqa: max-complexity=16
 
         if response.status_code != 200:
             # Probably a mis-configured kolibri
+            sys.stderr.write("---Debug information---\n")
+            sys.stderr.write(response.text)
+            sys.stderr.write("\n-----------------------\n")
             raise NotRunning(STATUS_SERVER_CONFIGURATION_ERROR)
 
     else:


Test patch: