Repository: inventree/InvenTree

Issue:
Can't start inventree server
It seems that error at `https://api.exchangerate.host/latest` blocks server startup.

```
# curl https://api.exchangerate.host/latest
<html>
<head><title>521 Origin Down</title></head>
<body bgcolor="white">
<center><h1>521 Origin Down</h1></center>
<hr><center>cloudflare-nginx</center>
</body>
</html>
```

<details>

```
# inv server
InvenTree Database Configuration
================================
ENGINE: django.db.backends.mysql
NAME: inventree
HOST: localhost
Base currency changed from USD to RUB
Updating exchange rates from https://api.exchangerate.host/latest
Using base currency 'RUB'
InvenTree Database Configuration
================================
ENGINE: django.db.backends.mysql
NAME: inventree
HOST: localhost
Base currency changed from USD to RUB
Updating exchange rates from https://api.exchangerate.host/latest
Using base currency 'RUB'
Watching for file changes with StatReloader
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/core/management/commands/runserver.py", line 110, in inner_run
    autoreload.raise_last_exception()
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    autoreload.check_errors(django.setup)()
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/var/projects/inventree/inventree/InvenTree/InvenTree/apps.py", line 24, in ready
    self.update_exchange_rates()
  File "/var/projects/inventree/inventree/InvenTree/InvenTree/apps.py", line 105, in update_exchange_rates
    update_exchange_rates()
  File "/var/projects/inventree/inventree/InvenTree/InvenTree/tasks.py", line 199, in update_exchange_rates
    backend.update_rates(base_currency=base)
  File "/var/projects/inventree/inventree/InvenTree/InvenTree/exchange.py", line 29, in update_rates
    super().update_rates(base=base_currency, symbols=symbols)
  File "/usr/lib64/python3.6/contextlib.py", line 52, in inner
    return func(*args, **kwds)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py", line 68, in update_rates
    for currency, value in self.get_rates(**params).items()
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py", line 80, in get_rates
    response = self.get_response(**params)
  File "/var/projects/inventree/inventree-env/lib64/python3.6/site-packages/djmoney/contrib/exchange/backends/base.py", line 48, in get_response
    response = urlopen(url, cafile=certifi.where())
  File "/usr/lib64/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib64/python3.6/urllib/request.py", line 532, in open
    response = meth(req, response)
  File "/usr/lib64/python3.6/urllib/request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib64/python3.6/urllib/request.py", line 570, in error
    return self._call_chain(*args)
  File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/lib64/python3.6/urllib/request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 521: Origin Down
```

</details>


Discussion:
Can not replicate but seems to be plausible. I will take a look at this.

Resolving patch:
diff --git a/InvenTree/InvenTree/exchange.py b/InvenTree/InvenTree/exchange.py
--- a/InvenTree/InvenTree/exchange.py
+++ b/InvenTree/InvenTree/exchange.py
@@ -1,4 +1,5 @@
 from common.settings import currency_code_default, currency_codes
+from urllib.error import HTTPError, URLError
 
 from djmoney.contrib.exchange.backends.base import SimpleExchangeBackend
 
@@ -26,4 +27,8 @@ def update_rates(self, base_currency=currency_code_default()):
 
         symbols = ','.join(currency_codes())
 
-        super().update_rates(base=base_currency, symbols=symbols)
+        try:
+            super().update_rates(base=base_currency, symbols=symbols)
+        # catch connection errors
+        except (HTTPError, URLError):
+            print('Encountered connection error while updating')


Test patch: