fix: replace broad except Exception with specific exception types
- jail_service: catch ValueError (fail2ban protocol error) instead of Exception - health.py: catch AttributeError (not OSError/TypeError) for defensive checks - ban_service: re-raise programming errors in geo lookup handlers - server_service: catch Fail2BanConnectionError, Fail2BanProtocolError, ValueError - config_writer: catch OSError instead of Exception Programming errors now bubble to global handler instead of being silently caught. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -84,7 +84,7 @@ async def health_check(
|
|||||||
components.append(
|
components.append(
|
||||||
ComponentHealth(name="scheduler", healthy=False, message="Not initialised"),
|
ComponentHealth(name="scheduler", healthy=False, message="Not initialised"),
|
||||||
)
|
)
|
||||||
except Exception: # pragma: no cover - defensive
|
except AttributeError: # pragma: no cover - defensive
|
||||||
scheduler_state = "unknown"
|
scheduler_state = "unknown"
|
||||||
components.append(
|
components.append(
|
||||||
ComponentHealth(name="scheduler", healthy=False, message="Not accessible"),
|
ComponentHealth(name="scheduler", healthy=False, message="Not accessible"),
|
||||||
@@ -100,10 +100,11 @@ async def health_check(
|
|||||||
components.append(
|
components.append(
|
||||||
ComponentHealth(name="cache", healthy=False, message="Not initialised"),
|
ComponentHealth(name="cache", healthy=False, message="Not initialised"),
|
||||||
)
|
)
|
||||||
except Exception: # pragma: no cover - defensive
|
except AttributeError: # pragma: no cover - defensive
|
||||||
cache_state = "uninitialised"
|
cache_state = "uninitialised"
|
||||||
|
components.append(
|
||||||
# --- fail2ban ---
|
ComponentHealth(name="cache", healthy=False, message="Not accessible"),
|
||||||
|
)
|
||||||
fail2ban_online: bool = server_status.online
|
fail2ban_online: bool = server_status.online
|
||||||
if not fail2ban_online:
|
if not fail2ban_online:
|
||||||
components.append(
|
components.append(
|
||||||
|
|||||||
@@ -481,6 +481,7 @@ async def list_bans(
|
|||||||
log.warning("ban_service_geo_lookup_failed", ip=ip)
|
log.warning("ban_service_geo_lookup_failed", ip=ip)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
log.error("ban_service_geo_lookup_unexpected_error", ip=ip, error=type(exc).__name__)
|
log.error("ban_service_geo_lookup_unexpected_error", ip=ip, error=type(exc).__name__)
|
||||||
|
raise # Bubble programming errors to global handler
|
||||||
|
|
||||||
items.append(
|
items.append(
|
||||||
DomainDashboardBanItem(
|
DomainDashboardBanItem(
|
||||||
@@ -648,7 +649,7 @@ async def bans_by_country(
|
|||||||
return ip, None
|
return ip, None
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
log.error("ban_service_geo_lookup_unexpected_error", ip=ip, error=type(exc).__name__)
|
log.error("ban_service_geo_lookup_unexpected_error", ip=ip, error=type(exc).__name__)
|
||||||
return ip, None
|
raise # Bubble programming errors to global handler
|
||||||
|
|
||||||
results = await asyncio.gather(*(_safe_lookup(ip) for ip in unique_ips))
|
results = await asyncio.gather(*(_safe_lookup(ip) for ip in unique_ips))
|
||||||
geo_map = {ip: geo for ip, geo in results if geo is not None}
|
geo_map = {ip: geo for ip, geo in results if geo is not None}
|
||||||
|
|||||||
@@ -159,12 +159,13 @@ async def _check_backend_cmd_supported(
|
|||||||
if state.backend_cmd_supported is not None:
|
if state.backend_cmd_supported is not None:
|
||||||
return state.backend_cmd_supported
|
return state.backend_cmd_supported
|
||||||
|
|
||||||
# Probe: send the command and catch any exception.
|
# Probe: send the command and catch only fail2ban protocol errors.
|
||||||
|
# Programming errors (TypeError, AttributeError) bubble up to global handler.
|
||||||
try:
|
try:
|
||||||
ok(await client.send(["get", jail_name, "backend"]))
|
ok(await client.send(["get", jail_name, "backend"]))
|
||||||
state.backend_cmd_supported = True
|
state.backend_cmd_supported = True
|
||||||
log.debug("backend_cmd_supported_detected")
|
log.debug("backend_cmd_supported_detected")
|
||||||
except Exception:
|
except ValueError:
|
||||||
state.backend_cmd_supported = False
|
state.backend_cmd_supported = False
|
||||||
log.debug("backend_cmd_unsupported_detected")
|
log.debug("backend_cmd_unsupported_detected")
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from typing import cast
|
|||||||
|
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
from app.exceptions import ServerOperationError
|
from app.exceptions import Fail2BanConnectionError, Fail2BanProtocolError, ServerOperationError
|
||||||
from app.models.server_domain import DomainServerSettings, DomainServerSettingsResult
|
from app.models.server_domain import DomainServerSettings, DomainServerSettingsResult
|
||||||
from app.models.server import ServerSettingsUpdate
|
from app.models.server import ServerSettingsUpdate
|
||||||
from app.utils.constants import FAIL2BAN_SOCKET_TIMEOUT
|
from app.utils.constants import FAIL2BAN_SOCKET_TIMEOUT
|
||||||
@@ -79,7 +79,7 @@ async def _safe_get(
|
|||||||
try:
|
try:
|
||||||
response = await client.send(command)
|
response = await client.send(command)
|
||||||
return ok(cast("Fail2BanResponse", response))
|
return ok(cast("Fail2BanResponse", response))
|
||||||
except Exception:
|
except (Fail2BanConnectionError, Fail2BanProtocolError, ValueError):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ def _write_parser_atomic(
|
|||||||
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
os.replace(tmp_path_str, str(path))
|
os.replace(tmp_path_str, str(path))
|
||||||
except Exception:
|
except OSError:
|
||||||
with contextlib.suppress(OSError):
|
with contextlib.suppress(OSError):
|
||||||
os.unlink(tmp_path_str)
|
os.unlink(tmp_path_str)
|
||||||
raise
|
raise
|
||||||
|
|||||||
Reference in New Issue
Block a user