Improve error reporting

This commit is contained in:
Ian Renton
2026-07-25 09:02:57 +01:00
parent c397009ada
commit 374a326874
17 changed files with 101 additions and 71 deletions
+2
View File
@@ -56,6 +56,8 @@ class HTTPAlertProvider(AlertProvider):
self.status = "Error"
logging.warning(f"HTTP {http_response.status_code} when calling {self.name} alerts API.")
except ConnectionError:
logging.warning(f"Connection error when accessing {self.name} alerts API.")
except Exception:
self.status = "Error"
logging.exception("Exception in HTTP JSON Alert Provider (" + self.name + ")")
+10 -2
View File
@@ -153,6 +153,8 @@ class LookupHelper:
logging.warning(f"HTTP {response.status_code} when downloading Country-files.com cty.plist.")
return False
except ConnectionError:
logging.warning(f"Connection error when downloading Clublog cty.xml.")
except Exception as e:
logging.error("Exception when downloading Clublog cty.xml", e)
return False
@@ -175,6 +177,8 @@ class LookupHelper:
logging.warning(f"HTTP {response.status_code} when downloading dxcc.json.")
return False
except ConnectionError:
logging.warning(f"Connection error when downloading dxcc.json.")
except Exception as e:
logging.error("Exception when downloading dxcc.json", e)
return False
@@ -519,8 +523,10 @@ class LookupHelper:
except (KeyError, ValueError):
continue
except ConnectionError:
logging.warning(f"Connection error when looking up callsign %s using QRZ", lookup_call)
except Exception:
logging.error("Exception when looking up QRZ data")
logging.error("Exception when looking up callsign %s using QRZ", lookup_call)
return None
# Not found in QRZ; cache None so we don't keep retrying
@@ -578,8 +584,10 @@ class LookupHelper:
except (KeyError, ValueError):
continue
except ConnectionError:
logging.warning(f"Connection error when looking up callsign %s using HamQTH", lookup_call)
except Exception:
logging.error("Exception when looking up HamQTH data")
logging.error("Exception when looking up callsign %s using HamQTH", lookup_call)
return None
# Not found in HamQTH; cache None so we don't keep retrying
+3 -1
View File
@@ -259,8 +259,10 @@ def populate_sig_ref_info(sig_ref):
else:
logging.warning("DME database did not contain data for ref %s", ref_id)
except ConnectionError:
logging.warning("Connection error when looking up sig_ref info for " + sig + " ref " + ref_id)
except Exception:
logging.warning("Exception when looking up sig_ref info for " + sig + " ref " + ref_id, exc_info=True)
logging.error("Exception when looking up sig_ref info for " + sig + " ref " + ref_id, exc_info=True)
return sig_ref
+8 -4
View File
@@ -127,11 +127,15 @@ class GIROIonosonde(SolarConditionsProvider):
from_str = from_time.strftime("%Y.%m.%d+%H:%M:%S")
to_str = to_time.strftime("%Y.%m.%d+%H:%M:%S")
url = f"{LGDC_URL}?ursiCode={ursi}&charName=foF2,MUFD,fmin&DMUF=3000&fromDate={from_str}&toDate={to_str}"
http_response = requests.get(url, headers=HTTP_HEADERS, timeout=(5, 15))
if not http_response.ok:
logging.warning(f"HTTP {http_response.status_code} when calling Giro ionosonde API.")
try:
http_response = requests.get(url, headers=HTTP_HEADERS, timeout=(5, 15))
if not http_response.ok:
logging.warning(f"HTTP {http_response.status_code} when calling Giro ionosonde API.")
return None, None, None
return self._parse_all(http_response.text)
except ConnectionError:
logging.warning("Connection error when accessing Giro ionosonde API.")
return None, None, None
return self._parse_all(http_response.text)
@staticmethod
def _parse_all(text):
@@ -51,6 +51,8 @@ class HTTPSolarConditionsProvider(SolarConditionsProvider):
self.status = "Error"
logging.warning(f"HTTP {http_response.status_code} when calling {self.name} solar conditions API.")
except ConnectionError:
logging.warning(f"Connection error when accessing {self.name} solar conditions API.")
except Exception:
self.status = "Error"
logging.exception("Exception in HTTP Solar Conditions Provider (" + self.name + ")")
+2
View File
@@ -115,6 +115,8 @@ class KC2GProp(SolarConditionsProvider):
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Updated KC2G ionosonde data for {updated_count} stations.")
except ConnectionError:
logging.warning("Connection error when accessing KC2G ionosonde API.")
except Exception:
self.status = "Error"
logging.exception("Exception in KC2G ionosonde data provider")
+32 -28
View File
@@ -1,3 +1,4 @@
import logging
import re
from datetime import datetime
@@ -35,34 +36,37 @@ class HEMA(HTTPSpotProvider):
new_spots = []
# OK, if the spot seed actually changed, now we make the real request for data.
if spot_seed_changed:
source_data = requests.get(self.SPOTS_URL, headers=HTTP_HEADERS, timeout=(5, 30))
source_data_items = source_data.text.split("=")
# Iterate through source data items.
for source_spot in source_data_items:
spot_items = source_spot.split(";")
# Any line with less than 9 items is not a proper spot line
if len(spot_items) >= 9:
# Fiddle with some data to extract bits we need. Freq/mode and spotter/comment come in combined fields.
freq_mode_match = re.search(self.FREQ_MODE_PATTERN, spot_items[5])
spotter_comment_match = re.search(self.SPOTTER_COMMENT_PATTERN, spot_items[6])
if not freq_mode_match or not spotter_comment_match:
continue
try:
source_data = requests.get(self.SPOTS_URL, headers=HTTP_HEADERS, timeout=(5, 30))
source_data_items = source_data.text.split("=")
# Iterate through source data items.
for source_spot in source_data_items:
spot_items = source_spot.split(";")
# Any line with less than 9 items is not a proper spot line
if len(spot_items) >= 9:
# Fiddle with some data to extract bits we need. Freq/mode and spotter/comment come in combined fields.
freq_mode_match = re.search(self.FREQ_MODE_PATTERN, spot_items[5])
spotter_comment_match = re.search(self.SPOTTER_COMMENT_PATTERN, spot_items[6])
if not freq_mode_match or not spotter_comment_match:
continue
# Convert to our spot format
spot = Spot(source=self.name,
dx_call=spot_items[2].upper(),
de_call=spotter_comment_match.group(1).upper(),
freq=float(freq_mode_match.group(1)) * 1000000,
mode=freq_mode_match.group(2).upper(),
comment=spotter_comment_match.group(2),
sig="HEMA",
sig_refs=[SIGRef(id=spot_items[3].upper(), sig="HEMA", name=spot_items[4])],
time=datetime.strptime(spot_items[0], "%d/%m/%Y %H:%M").replace(
tzinfo=pytz.UTC).timestamp(),
dx_latitude=float(spot_items[7]),
dx_longitude=float(spot_items[8]))
# Convert to our spot format
spot = Spot(source=self.name,
dx_call=spot_items[2].upper(),
de_call=spotter_comment_match.group(1).upper(),
freq=float(freq_mode_match.group(1)) * 1000000,
mode=freq_mode_match.group(2).upper(),
comment=spotter_comment_match.group(2),
sig="HEMA",
sig_refs=[SIGRef(id=spot_items[3].upper(), sig="HEMA", name=spot_items[4])],
time=datetime.strptime(spot_items[0], "%d/%m/%Y %H:%M").replace(
tzinfo=pytz.UTC).timestamp(),
dx_latitude=float(spot_items[7]),
dx_longitude=float(spot_items[8]))
# Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do
# that for us.
new_spots.append(spot)
# Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other
# code will do that for us.
new_spots.append(spot)
except ConnectionError:
logging.warning("Connection error when accessing HEMA spots API.")
return new_spots
+2
View File
@@ -56,6 +56,8 @@ class HTTPSpotProvider(SpotProvider):
self.status = "Error"
logging.warning(f"HTTP {http_response.status_code} when calling {self.name} spot API.")
except ConnectionError:
logging.warning(f"Connection error when accessing {self.name} spots API.")
except Exception:
self.status = "Error"
logging.exception("Exception in HTTP JSON Spot Provider (" + self.name + ")")
+25 -21
View File
@@ -1,3 +1,4 @@
import logging
from datetime import datetime
import requests
@@ -33,26 +34,29 @@ class SOTA(HTTPSpotProvider):
new_spots = []
# OK, if the epoch actually changed, now we make the real request for data.
if epoch_changed:
source_data = requests.get(self.SPOTS_URL, headers=HTTP_HEADERS, timeout=(5, 30)).json()
# Iterate through source data
for source_spot in source_data:
# Convert to our spot format
spot = Spot(source=self.name,
source_id=source_spot["id"],
dx_call=source_spot["activatorCallsign"].upper(),
dx_name=source_spot["activatorName"],
de_call=source_spot["callsign"].upper(),
freq=(float(source_spot["frequency"]) * 1000000) if (
source_spot["frequency"] is not None) else None,
# Seen SOTA spots with no frequency!
mode=source_spot["mode"].upper(),
comment=source_spot["comments"],
sig="SOTA",
sig_refs=[SIGRef(id=source_spot["summitCode"], sig="SOTA", name=source_spot["summitName"],
activation_score=source_spot["points"])],
time=datetime.fromisoformat(source_spot["timeStamp"].replace("Z", "+00:00")).timestamp())
try:
source_data = requests.get(self.SPOTS_URL, headers=HTTP_HEADERS, timeout=(5, 30)).json()
# Iterate through source data
for source_spot in source_data:
# Convert to our spot format
spot = Spot(source=self.name,
source_id=source_spot["id"],
dx_call=source_spot["activatorCallsign"].upper(),
dx_name=source_spot["activatorName"],
de_call=source_spot["callsign"].upper(),
freq=(float(source_spot["frequency"]) * 1000000) if (
source_spot["frequency"] is not None) else None,
# Seen SOTA spots with no frequency!
mode=source_spot["mode"].upper(),
comment=source_spot["comments"],
sig="SOTA",
sig_refs=[SIGRef(id=source_spot["summitCode"], sig="SOTA", name=source_spot["summitName"],
activation_score=source_spot["points"])],
time=datetime.fromisoformat(source_spot["timeStamp"].replace("Z", "+00:00")).timestamp())
# Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do
# that for us.
new_spots.append(spot)
# Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do
# that for us.
new_spots.append(spot)
except ConnectionError:
logging.warning("Connection error when accessing SOTA spots API")
return new_spots
+1 -1
View File
@@ -76,7 +76,7 @@
</div>
<script src="/js/add-spot.js?v=1784966035"></script>
<script src="/js/add-spot.js?v=1784966577"></script>
<script>$(document).ready(function () {
$("#nav-link-add-spot").addClass("active");
}); <!-- highlight active page in nav --></script>
+1 -1
View File
@@ -75,7 +75,7 @@
</div>
<script src="/js/alerts.js?v=1784966035"></script>
<script src="/js/alerts.js?v=1784966578"></script>
<script>$(document).ready(function () {
$("#nav-link-alerts").addClass("active");
}); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -75,8 +75,8 @@
<script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script>
<script src="/js/spotsbandsandmap.js?v=1784966035"></script>
<script src="/js/bands.js?v=1784966035"></script>
<script src="/js/spotsbandsandmap.js?v=1784966577"></script>
<script src="/js/bands.js?v=1784966577"></script>
<script>$(document).ready(function () {
$("#nav-link-bands").addClass("active");
}); <!-- highlight active page in nav --></script>
+5 -5
View File
@@ -1,6 +1,6 @@
{% extends "skeleton.html" %}
{% block head_extra %}
<link rel="stylesheet" href="/css/style.css?v=1784966035" type="text/css">
<link rel="stylesheet" href="/css/style.css?v=1784966577" type="text/css">
<link href="/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
<link href="/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
<link href="/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
@@ -10,10 +10,10 @@
<script src="/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
<script src="/vendor/js/tinycolor2-1.6.0.min.js"></script>
<script src="/js/utils.js?v=1784966035"></script>
<script src="/js/ui-ham.js?v=1784966035"></script>
<script src="/js/geo.js?v=1784966035"></script>
<script src="/js/common.js?v=1784966035"></script>
<script src="/js/utils.js?v=1784966577"></script>
<script src="/js/ui-ham.js?v=1784966577"></script>
<script src="/js/geo.js?v=1784966577"></script>
<script src="/js/common.js?v=1784966577"></script>
{% end %}
{% block body %}
<div class="container">
+1 -1
View File
@@ -284,7 +284,7 @@
</div>
<script src="/vendor/js/chart-4.4.9.umd.min.js"></script>
<script src="/js/conditions.js?v=1784966035"></script>
<script src="/js/conditions.js?v=1784966577"></script>
<script>$(document).ready(function () {
$("#nav-link-conditions").addClass("active");
}); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -95,8 +95,8 @@
<script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script>
<script src="/js/spotsbandsandmap.js?v=1784966035"></script>
<script src="/js/map.js?v=1784966035"></script>
<script src="/js/spotsbandsandmap.js?v=1784966578"></script>
<script src="/js/map.js?v=1784966578"></script>
<script>$(document).ready(function () {
$("#nav-link-map").addClass("active");
}); <!-- highlight active page in nav --></script>
+2 -2
View File
@@ -116,8 +116,8 @@
<script>
let spotProvidersEnabledByDefault = {% raw json_encode(web_ui_options["spot-providers-enabled-by-default"]) %};
</script>
<script src="/js/spotsbandsandmap.js?v=1784966035"></script>
<script src="/js/spots.js?v=1784966035"></script>
<script src="/js/spotsbandsandmap.js?v=1784966577"></script>
<script src="/js/spots.js?v=1784966577"></script>
<script>$(document).ready(function () {
$("#nav-link-spots").addClass("active");
}); <!-- highlight active page in nav --></script>
+1 -1
View File
@@ -59,7 +59,7 @@
</div>
</div>
<script src="/js/status.js?v=1784966035"></script>
<script src="/js/status.js?v=1784966577"></script>
<script>
$(document).ready(function () {
$("#nav-link-status").addClass("active");