Repository: lutris/lutris

Issue:
Handle HTTP 403 errors
I'm not sure why Lutris.net was 403-ing this user from our Discord server but the error should be handled:
```
2021-12-07 21:02:05,630: Magic not available. Unable to automatically find game executables. Please install python-magic
2021-12-07 21:02:05,684: Starting Lutris 0.5.9.1
2021-12-07 21:02:05,712: No cores found
2021-12-07 21:02:10,656: Failed to get components: HTTP Error 403: Forbidden
2021-12-07 21:02:11,263: Failed to read content length on response from https://api.github.com/repos/lutris/dxvk/releases
2021-12-07 21:02:13,210: Startup complete
INFO     2021-12-07 21:02:13,213 [startup.check_driver:61]:Running Intel Open Source Technology Center Mesa driver 21.2.5 on Mesa DRI Intel(R) HD Graphics 4600 (HSW GT2) (0x412)
INFO     2021-12-07 21:02:13,214 [startup.check_driver:73]:GPU: 8086:0412 1462:7817 (i915 drivers)
ERROR    2021-12-07 21:02:13,214 [startup.check_libs:108]:i386 libgnutls.so.30 missing (needed by gnutls)
MESA-INTEL: warning: Haswell Vulkan support is incomplete
DEBUG    2021-12-07 21:02:13,512 [lutriswindow.update_store:451]:Showing 1 games
DEBUG    2021-12-07 21:05:25,739 [__init__.fetch_script:22]:Fetching installer https://lutris.net/api/installers/genshin-impact
DEBUG    2021-12-07 21:05:25,739 [http.get:81]:GET https://lutris.net/api/installers/genshin-impact
DEBUG    2021-12-07 21:05:27,272 [application.show_window:259]:Showing window <class 'lutris.gui.installerwindow.InstallerWindow'>genshin-impact
DEBUG    2021-12-07 21:05:28,697 [displayconfig.get_current_resolution:624]:Retrieving current resolution
INFO     2021-12-07 21:05:39,350 [runner.get_runner_version:303]:Getting runner information for wine
DEBUG    2021-12-07 21:05:39,351 [http.get:81]:GET https://lutris.net/api/runners/wine
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/lutris/util/http.py", line 90, in get
    request = urllib.request.urlopen(req, timeout=self.timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/usr/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/usr/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/lutris/installer/interpreter.py", line 160, in launch_install
    self.runners_to_install = self.get_runners_to_install()
  File "/usr/lib/python3.9/site-packages/lutris/installer/interpreter.py", line 213, in get_runners_to_install
    default_wine = runner.get_runner_version() or {}
  File "/usr/lib/python3.9/site-packages/lutris/runners/runner.py", line 309, in get_runner_version
    runner_info = request.get().json
  File "/usr/lib/python3.9/site-packages/lutris/util/http.py", line 94, in get
    raise HTTPError("%s" % error, code=error.code)
lutris.util.http.HTTPError: HTTP Error 403: Forbidden
```


Discussion:

Resolving patch:
diff --git a/lutris/runners/runner.py b/lutris/runners/runner.py
--- a/lutris/runners/runner.py
+++ b/lutris/runners/runner.py
@@ -13,7 +13,7 @@
 from lutris.runners import RunnerInstallationError
 from lutris.util import system
 from lutris.util.extract import ExtractFailure, extract_archive
-from lutris.util.http import Request
+from lutris.util.http import HTTPError, Request
 from lutris.util.linux import LINUX_SYSTEM
 from lutris.util.log import logger
 
@@ -298,17 +298,26 @@ def get_runner_version(self, version=None):
             version (str): Optional version to lookup, will return this one if found
 
         Returns:
-            dict: Dict containing version, architecture and url for the runner
+            dict: Dict containing version, architecture and url for the runner, None
+            if the data can't be retrieved.
         """
         logger.info(
             "Getting runner information for %s%s",
             self.name,
             " (version: %s)" % version if version else "",
         )
-        request = Request("{}/api/runners/{}".format(settings.SITE_URL, self.name))
-        runner_info = request.get().json
+
+        try:
+            request = Request("{}/api/runners/{}".format(settings.SITE_URL, self.name))
+            runner_info = request.get().json
+
+            if not runner_info:
+                logger.error("Failed to get runner information")
+        except HTTPError as ex:
+            logger.error("Unable to get runner information: %s", ex)
+            runner_info = None
+
         if not runner_info:
-            logger.error("Failed to get runner information")
             return
 
         versions = runner_info.get("versions") or []


Test patch: