prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Catch ValueError during network discovery for when JSON parsing fails
  <!--
  Instructions:
   * Fill out the sections below, replace …'s with information about your issue
   * Use the 'preview' function above this text box to verify formatting before submitting
  -->
  
  ### Observed behavior
  <!--
  Description of the behavior that was observed, including screenshots or other references when applicable
  -->
  
  When trying to import content channels (from local network or internet), no error message is produced even though the connection isn't established. (The "trying to connect" message stays on forever) This happens when there is a typo in the address. (I used kolibri-demo.learningequality.omg)  When there's no internet, an error message DOES get produced. 
  
  ### Expected behavior
  <!--
  Description of what behavior was expected but did not occur
  -->
  
  An error message should've been produced.
  
  ### User-facing consequences
  <!--
  Implications and real-world consequences for learners, coaches, admins, and other users of the application
  -->
  
  The user will not know how long they have to wait to see if the connection is being established.
  
  ### Errors and logs
  <!--
  Relevant logs from:
   * the command line
   * ~/.kolibri/logs/kolibri.txt
   * the browser console
  
  Please wrap errors in triple backticks for clean formatting like this:
  ```
  01:10 info: something happened
  01:12 error: something bad happened
  ```
  -->
  
  …
  
  ### Steps to reproduce
  <!--
  Precise steps that someone else can follow in order to see this behavior
  -->
  
  Import content channels from local network or internet >input "kolibri-demo.learningequality.omg" or something else with a typo in it.
  
  ### Context
  <!--
  Tell us about your environment, including:
   * Kolibri version
   * Operating system
   * Browser
  -->
  
  Kolibri version: 0.14.3
  Operating system: Android 5.1
  Browser: Android App
  Device: BLU Advance 5.0
  
  
  </issue>
  <code>
  [start of kolibri/core/discovery/utils/network/client.py]
  1 import logging
  2 
  3 import requests
  4 from six.moves.urllib.parse import urljoin
  5 
  6 from . import errors
  7 from .urls import get_normalized_url_variations
  8 
  9 logger = logging.getLogger(__name__)
  10 
  11 
  12 class NetworkClient(object):
  13     DEFAULT_TIMEOUT_IN_SECS = 5
  14 
  15     def __init__(self, base_url=None, address=None, timeout=None, **kwargs):
  16         """If an explicit base_url is already known, provide that. If a vague address is provided, we can try to infer the base_url"""
  17         if not base_url and not address:
  18             raise Exception(
  19                 "You must provide either a `base_url` or `address` argument"
  20             )
  21         self.timeout = timeout or self.DEFAULT_TIMEOUT_IN_SECS
  22         self.session = requests.Session(**kwargs)
  23         if base_url:
  24             self.base_url = self._attempt_connections([base_url])
  25         else:
  26             # normalize the URL and try a number of variations until we find one that's able to connect
  27             logger.info(
  28                 "Attempting connections to variations of the URL: {}".format(address)
  29             )
  30             self.base_url = self._attempt_connections(
  31                 get_normalized_url_variations(address)
  32             )
  33 
  34     def _attempt_connections(self, urls):
  35         # try each of the URLs in turn, returning the first one that succeeds
  36         for url in urls:
  37             try:
  38                 logger.info("Attempting connection to: {}".format(url))
  39                 response = self.get(
  40                     "/api/public/info/",
  41                     base_url=url,
  42                     timeout=self.timeout,
  43                     allow_redirects=True,
  44                 )
  45                 # check that we successfully connected, and if we were redirected that it's still the right endpoint
  46                 if response.status_code == 200 and response.url.rstrip("/").endswith(
  47                     "/api/public/info"
  48                 ):
  49                     self.info = response.json()
  50                     if self.info["application"] not in ["studio", "kolibri"]:
  51                         raise requests.RequestException(
  52                             "Server is not running Kolibri or Studio"
  53                         )
  54                     logger.info("Success! We connected to: {}".format(response.url))
  55                     return response.url.rstrip("/").replace("api/public/info", "")
  56             except (requests.RequestException) as e:
  57                 logger.info("Unable to connect: {}".format(e))
  58 
  59         # we weren't able to connect to any of the URL variations, so all we can do is throw
  60         raise errors.NetworkLocationNotFound()
  61 
  62     def get(self, path, **kwargs):
  63         return self.request("get", path, **kwargs)
  64 
  65     def head(self, path, **kwargs):
  66         return self.request("head", path, **kwargs)
  67 
  68     def request(self, method, path, base_url=None, **kwargs):
  69         base_url = base_url or self.base_url
  70         url = urljoin(base_url, path)
  71         response = getattr(self.session, method)(url, **kwargs)
  72         response.raise_for_status()
  73         return response
  74
  [end of kolibri/core/discovery/utils/network/client.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/kolibri/core/discovery/utils/network/client.py b/kolibri/core/discovery/utils/network/client.py
  --- a/kolibri/core/discovery/utils/network/client.py
  +++ b/kolibri/core/discovery/utils/network/client.py
  @@ -55,6 +55,10 @@
                       return response.url.rstrip("/").replace("api/public/info", "")
               except (requests.RequestException) as e:
                   logger.info("Unable to connect: {}".format(e))
  +            except ValueError:
  +                logger.info(
  +                    "Invalid JSON returned when attempting to connect to a remote server"
  +                )
   
           # we weren't able to connect to any of the URL variations, so all we can do is throw
           raise errors.NetworkLocationNotFound()
  
verification_info: {"golden_diff": "diff --git a/kolibri/core/discovery/utils/network/client.py b/kolibri/core/discovery/utils/network/client.py\n--- a/kolibri/core/discovery/utils/network/client.py\n+++ b/kolibri/core/discovery/utils/network/client.py\n@@ -55,6 +55,10 @@\n                     return response.url.rstrip(\"/\").replace(\"api/public/info\", \"\")\n             except (requests.RequestException) as e:\n                 logger.info(\"Unable to connect: {}\".format(e))\n+            except ValueError:\n+                logger.info(\n+                    \"Invalid JSON returned when attempting to connect to a remote server\"\n+                )\n \n         # we weren't able to connect to any of the URL variations, so all we can do is throw\n         raise errors.NetworkLocationNotFound()\n", "issue": "Catch ValueError during network discovery for when JSON parsing fails\n<!--\r\nInstructions:\r\n * Fill out the sections below, replace \u2026's with information about your issue\r\n * Use the 'preview' function above this text box to verify formatting before submitting\r\n-->\r\n\r\n### Observed behavior\r\n<!--\r\nDescription of the behavior that was observed, including screenshots or other references when applicable\r\n-->\r\n\r\nWhen trying to import content channels (from local network or internet), no error message is produced even though the connection isn't established. (The \"trying to connect\" message stays on forever) This happens when there is a typo in the address. (I used kolibri-demo.learningequality.omg)  When there's no internet, an error message DOES get produced. \r\n\r\n### Expected behavior\r\n<!--\r\nDescription of what behavior was expected but did not occur\r\n-->\r\n\r\nAn error message should've been produced.\r\n\r\n### User-facing consequences\r\n<!--\r\nImplications and real-world consequences for learners, coaches, admins, and other users of the application\r\n-->\r\n\r\nThe user will not know how long they have to wait to see if the connection is being established.\r\n\r\n### Errors and logs\r\n<!--\r\nRelevant logs from:\r\n * the command line\r\n * ~/.kolibri/logs/kolibri.txt\r\n * the browser console\r\n\r\nPlease wrap errors in triple backticks for clean formatting like this:\r\n```\r\n01:10 info: something happened\r\n01:12 error: something bad happened\r\n```\r\n-->\r\n\r\n\u2026\r\n\r\n### Steps to reproduce\r\n<!--\r\nPrecise steps that someone else can follow in order to see this behavior\r\n-->\r\n\r\nImport content channels from local network or internet >input \"kolibri-demo.learningequality.omg\" or something else with a typo in it.\r\n\r\n### Context\r\n<!--\r\nTell us about your environment, including:\r\n * Kolibri version\r\n * Operating system\r\n * Browser\r\n-->\r\n\r\nKolibri version: 0.14.3\r\nOperating system: Android 5.1\r\nBrowser: Android App\r\nDevice: BLU Advance 5.0\r\n\n", "before_files": [{"content": "import logging\n\nimport requests\nfrom six.moves.urllib.parse import urljoin\n\nfrom . import errors\nfrom .urls import get_normalized_url_variations\n\nlogger = logging.getLogger(__name__)\n\n\nclass NetworkClient(object):\n    DEFAULT_TIMEOUT_IN_SECS = 5\n\n    def __init__(self, base_url=None, address=None, timeout=None, **kwargs):\n        \"\"\"If an explicit base_url is already known, provide that. If a vague address is provided, we can try to infer the base_url\"\"\"\n        if not base_url and not address:\n            raise Exception(\n                \"You must provide either a `base_url` or `address` argument\"\n            )\n        self.timeout = timeout or self.DEFAULT_TIMEOUT_IN_SECS\n        self.session = requests.Session(**kwargs)\n        if base_url:\n            self.base_url = self._attempt_connections([base_url])\n        else:\n            # normalize the URL and try a number of variations until we find one that's able to connect\n            logger.info(\n                \"Attempting connections to variations of the URL: {}\".format(address)\n            )\n            self.base_url = self._attempt_connections(\n                get_normalized_url_variations(address)\n            )\n\n    def _attempt_connections(self, urls):\n        # try each of the URLs in turn, returning the first one that succeeds\n        for url in urls:\n            try:\n                logger.info(\"Attempting connection to: {}\".format(url))\n                response = self.get(\n                    \"/api/public/info/\",\n                    base_url=url,\n                    timeout=self.timeout,\n                    allow_redirects=True,\n                )\n                # check that we successfully connected, and if we were redirected that it's still the right endpoint\n                if response.status_code == 200 and response.url.rstrip(\"/\").endswith(\n                    \"/api/public/info\"\n                ):\n                    self.info = response.json()\n                    if self.info[\"application\"] not in [\"studio\", \"kolibri\"]:\n                        raise requests.RequestException(\n                            \"Server is not running Kolibri or Studio\"\n                        )\n                    logger.info(\"Success! We connected to: {}\".format(response.url))\n                    return response.url.rstrip(\"/\").replace(\"api/public/info\", \"\")\n            except (requests.RequestException) as e:\n                logger.info(\"Unable to connect: {}\".format(e))\n\n        # we weren't able to connect to any of the URL variations, so all we can do is throw\n        raise errors.NetworkLocationNotFound()\n\n    def get(self, path, **kwargs):\n        return self.request(\"get\", path, **kwargs)\n\n    def head(self, path, **kwargs):\n        return self.request(\"head\", path, **kwargs)\n\n    def request(self, method, path, base_url=None, **kwargs):\n        base_url = base_url or self.base_url\n        url = urljoin(base_url, path)\n        response = getattr(self.session, method)(url, **kwargs)\n        response.raise_for_status()\n        return response\n", "path": "kolibri/core/discovery/utils/network/client.py"}]}