Consolidate domain exceptions into app.exceptions

Move all shared domain exception classes to backend/app/exceptions.py and update services/routers to import the canonical exceptions. Update docs to reflect the shared exceptions source.
This commit is contained in:
2026-04-13 19:35:12 +02:00
parent 4b2e86edbb
commit a5674f9e4c
10 changed files with 199 additions and 381 deletions

View File

@@ -2,10 +2,18 @@ from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, HTTPException, Path, Query, status
from fastapi import APIRouter, HTTPException, Path, Query, Request, status
from app.dependencies import AuthDep, Fail2BanConfigDirDep, Fail2BanSocketDep
from app.exceptions import ConfigWriteError
from app.exceptions import (
ActionAlreadyExistsError,
ActionNameError,
ActionNotFoundError,
ActionReadonlyError,
ConfigWriteError,
JailNameError,
JailNotFoundInConfigError,
)
from app.models.config import (
ActionConfig,
ActionCreateRequest,
@@ -14,13 +22,6 @@ from app.models.config import (
AssignActionRequest,
)
from app.services import action_config_service
from app.services.action_config_service import (
ActionAlreadyExistsError,
ActionNameError,
ActionNotFoundError,
ActionReadonlyError,
)
from app.services.jail_config_service import JailNameError, JailNotFoundInConfigError
router: APIRouter = APIRouter()
@@ -29,6 +30,11 @@ _ActionNamePath = Annotated[
Path(description='Action base name, e.g. ``iptables`` or ``iptables.conf``.'),
]
_NamePath = Annotated[
str,
Path(description='Jail name as configured in fail2ban.'),
]
def _action_not_found(name: str) -> HTTPException:
return HTTPException(
@@ -36,6 +42,17 @@ def _action_not_found(name: str) -> HTTPException:
detail=f"Action not found: {name!r}",
)
def _bad_request(message: str) -> HTTPException:
return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)
def _not_found(name: str) -> HTTPException:
return HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Jail not found: {name!r}",
)
@router.get(
"/actions",
response_model=ActionListResponse,

View File

@@ -2,26 +2,27 @@ from __future__ import annotations
from typing import Annotated
from fastapi import APIRouter, HTTPException, Path, Query, status
from fastapi import APIRouter, HTTPException, Path, Query, Request, status
from app.dependencies import AuthDep, Fail2BanConfigDirDep, Fail2BanSocketDep
from app.exceptions import ConfigWriteError
from app.models.config import (
AssignFilterRequest,
FilterConfig,
FilterConfigUpdate,
FilterCreateRequest,
FilterListResponse,
)
from app.services import filter_config_service
from app.services.filter_config_service import (
from app.exceptions import (
ConfigWriteError,
FilterAlreadyExistsError,
FilterInvalidRegexError,
FilterNameError,
FilterNotFoundError,
FilterReadonlyError,
JailNameError,
JailNotFoundInConfigError,
)
from app.services.jail_config_service import JailNameError, JailNotFoundInConfigError
from app.models.config import (
AssignFilterRequest,
FilterConfig,
FilterCreateRequest,
FilterListResponse,
FilterUpdateRequest,
)
from app.services import filter_config_service
router: APIRouter = APIRouter()
@@ -42,6 +43,21 @@ def _filter_not_found(name: str) -> HTTPException:
detail=f"Filter not found: {name!r}",
)
def _bad_request(message: str) -> HTTPException:
return HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)
def _unprocessable(message: str) -> HTTPException:
return HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=message)
def _not_found(name: str) -> HTTPException:
return HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Jail not found: {name!r}",
)
@router.get(
"/filters",
response_model=FilterListResponse,

View File

@@ -15,7 +15,12 @@ from app.dependencies import (
from app.exceptions import (
ConfigOperationError,
ConfigValidationError,
ConfigWriteError,
JailAlreadyActiveError,
JailAlreadyInactiveError,
JailNameError,
JailNotFoundError,
JailNotFoundInConfigError,
)
from app.models.config import (
ActivateJailRequest,
@@ -30,13 +35,6 @@ from app.models.config import (
RollbackResponse,
)
from app.services import config_service, jail_config_service, jail_service
from app.services.jail_config_service import (
ConfigWriteError,
JailAlreadyActiveError,
JailAlreadyInactiveError,
JailNameError,
JailNotFoundInConfigError,
)
from app.utils.fail2ban_client import Fail2BanConnectionError
router: APIRouter = APIRouter()