mirror of
https://github.com/ARUP-CAS/aiscr-qgis-amcr-viewer.git
synced 2026-10-09 12:27:36 +02:00
fix: diagnostika prázdných výsledků z API (#58)
- logování odeslané URL a chyb z těla odpovědi v _api_get_json
- výpis filtrů z dialogu před zahájením stahování
- rozlišení chyby API od prázdného výsledku (api_error)
- dávky geometrií PIAN hlásí chybějící blok 'response'
API vrací chyby s HTTP 200 a klíčem 'error' místo bloku 'response'; resp_json.get('response', {}) z toho udělal prázdný výsledek, takže neplatný parametr, prázdné okno mapy i chyba serveru končily stejnou hláškou "Žádné záznamy nenalezeny".
This commit is contained in:
1 parent
4699dd9c95
commit
4ed99d73d9
1 file changed
+66
-2
@@ -46,6 +46,14 @@ def _log(msg: str, level=Qgis.MessageLevel.Info):
|
||||
QgsMessageLog.logMessage(msg, "AMČR login", level)
|
||||
|
||||
|
||||
def _log_data(msg: str, level=Qgis.MessageLevel.Info):
|
||||
"""
|
||||
Shortcut: writes a message to the QGIS log used by the data download
|
||||
(Messages panel → AMČR tab).
|
||||
"""
|
||||
QgsMessageLog.logMessage(msg, "AMČR", level)
|
||||
|
||||
|
||||
def login_to_api(username: str, password: str):
|
||||
"""
|
||||
Logs in to the Digiarchiv API using a username and password.
|
||||
@@ -190,6 +198,21 @@ def _api_get_json(url, params, timeout=30) -> dict:
|
||||
_log("Přihlašovací údaje nejsou uloženy – pokračuji anonymně.",
|
||||
Qgis.MessageLevel.Warning)
|
||||
|
||||
# Log the URL that was actually sent, so a query returning nothing can
|
||||
# be replayed in a browser instead of being reconstructed from the code
|
||||
url_log = resp.url
|
||||
if len(url_log) > 500:
|
||||
url_log = f"{url_log[:500]}… (celkem {len(resp.url)} znaků)"
|
||||
_log_data(f"GET {url_log}")
|
||||
|
||||
# The API reports errors with HTTP 200 and an 'error' key instead of
|
||||
# a 'response' block – without this the caller sees only empty results
|
||||
if isinstance(body, dict) and body.get("error"):
|
||||
_log_data(
|
||||
f"API vrátilo chybu: {body['error']}",
|
||||
Qgis.MessageLevel.Critical
|
||||
)
|
||||
|
||||
if body is None:
|
||||
raise ValueError(
|
||||
f"API nevrátilo platný JSON (HTTP {resp.status_code})"
|
||||
@@ -312,6 +335,14 @@ def load_amcr_data(canvas, bb, filters=None,
|
||||
else:
|
||||
base_params[key] = str(value).strip()
|
||||
|
||||
# Filters exactly as they arrived from the dialog – an empty result
|
||||
# caused by a stray filter is otherwise indistinguishable from an
|
||||
# empty map window
|
||||
_log_data(
|
||||
f"Stahuji '{typ_dat}' (bbox={bb}, komponenty={komponenty}), "
|
||||
f"filtry: {filters if filters else 'žádné'}"
|
||||
)
|
||||
|
||||
docs = []
|
||||
current_page = 0
|
||||
BATCH_DOCS = 500 # Records per API request
|
||||
@@ -342,6 +373,10 @@ def load_amcr_data(canvas, bb, filters=None,
|
||||
# gets an explicit error/warning instead of a silent partial result
|
||||
network_error = False
|
||||
|
||||
# Set when the API answers with an error instead of a result set –
|
||||
# keeps an invalid parameter distinguishable from an empty result
|
||||
api_error = False
|
||||
|
||||
# --- API PAGINATION LOOP ---
|
||||
while True:
|
||||
base_params['rows'] = BATCH_DOCS
|
||||
@@ -352,11 +387,24 @@ def load_amcr_data(canvas, bb, filters=None,
|
||||
|
||||
try:
|
||||
resp_json = _api_get_json(url, params=base_params, timeout=30)
|
||||
data = resp_json.get('response', {})
|
||||
|
||||
# Errors arrive with HTTP 200 and no 'response' block;
|
||||
# _api_get_json has already logged the reason
|
||||
if 'response' not in resp_json:
|
||||
api_error = True
|
||||
break
|
||||
|
||||
data = resp_json['response']
|
||||
batch_docs = data.get('docs', [])
|
||||
num_found = data.get('numFound', 0)
|
||||
|
||||
if not batch_docs:
|
||||
if current_page == 0:
|
||||
_log_data(
|
||||
"Dotaz proběhl v pořádku, ale nevrátil žádný "
|
||||
f"záznam (numFound={num_found}).",
|
||||
Qgis.MessageLevel.Warning
|
||||
)
|
||||
break
|
||||
|
||||
fetched_total += len(batch_docs)
|
||||
@@ -416,6 +464,15 @@ def load_amcr_data(canvas, bb, filters=None,
|
||||
)
|
||||
return
|
||||
|
||||
if api_error and not docs:
|
||||
iface.messageBar().pushMessage(
|
||||
"AMCR",
|
||||
"Dotaz na API selhal – podrobnosti v panelu Zprávy, "
|
||||
"záložka AMČR.",
|
||||
level=Qgis.MessageLevel.Critical
|
||||
)
|
||||
return
|
||||
|
||||
if not docs:
|
||||
iface.messageBar().pushMessage(
|
||||
"AMCR",
|
||||
@@ -701,7 +758,14 @@ def load_amcr_data(canvas, bb, filters=None,
|
||||
try:
|
||||
QApplication.processEvents()
|
||||
r_json = _api_get_json(url, params=params_pian, timeout=15)
|
||||
docs_pian.extend(r_json.get('response', {}).get('docs', []))
|
||||
if 'response' not in r_json:
|
||||
QgsMessageLog.logMessage(
|
||||
"API nevrátilo geometrie PIAN pro dávku "
|
||||
f"{i // BATCH_PIAN + 1} – viz chyba výše.",
|
||||
"AMČR", Qgis.MessageLevel.Warning
|
||||
)
|
||||
continue
|
||||
docs_pian.extend(r_json['response'].get('docs', []))
|
||||
except requests.exceptions.RequestException as e:
|
||||
# Network is down – stop immediately instead of
|
||||
# uselessly retrying every remaining batch
|
||||
|
||||
Reference in new issue
Block a user