Enhance CSV metadata with error tracking for mosaics and tiles
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
Structured HTTP download result and error classification.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import requests
|
||||
|
||||
# public constants for error_class
|
||||
PERMANENT_MISSING = "permanent_missing"
|
||||
TRANSIENT = "transient"
|
||||
UNKNOWN = "unknown"
|
||||
OK = "" # success (no error class)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DownloadResult:
|
||||
"""Result of a streaming download (after all retries if applicable)."""
|
||||
|
||||
size: int
|
||||
status_code: int | None
|
||||
error: str | None
|
||||
error_class: str
|
||||
|
||||
@property
|
||||
def ok(self) -> bool:
|
||||
return self.size > 0 and self.error is None
|
||||
|
||||
|
||||
def classify_http_error(
|
||||
status_code: int | None, exc: BaseException | None
|
||||
) -> str:
|
||||
"""
|
||||
404/410 => likely gone forever.
|
||||
5xx and transport/timeouts => retry may help.
|
||||
"""
|
||||
if status_code in (404, 410):
|
||||
return PERMANENT_MISSING
|
||||
if status_code is not None and 500 <= status_code < 600:
|
||||
return TRANSIENT
|
||||
if exc is not None:
|
||||
if isinstance(
|
||||
exc,
|
||||
(
|
||||
requests.Timeout,
|
||||
requests.ConnectTimeout,
|
||||
requests.ReadTimeout,
|
||||
),
|
||||
):
|
||||
return TRANSIENT
|
||||
if isinstance(exc, (requests.exceptions.ConnectionError, OSError)):
|
||||
return TRANSIENT
|
||||
if isinstance(exc, requests.exceptions.ChunkedEncodingError):
|
||||
return TRANSIENT
|
||||
return UNKNOWN
|
||||
|
||||
|
||||
def error_code_str(status_code: int | None) -> str:
|
||||
if status_code is None:
|
||||
return ""
|
||||
return str(status_code)
|
||||
Reference in New Issue
Block a user