Move ConfigDirError, ConfigFileNotFoundError, ConfigFileExistsError, ConfigFileWriteError, and ConfigFileNameError from raw_config_io_service into the shared domain exception module. Update router and tests to import the exceptions from app.exceptions.
190 lines
5.7 KiB
Python
190 lines
5.7 KiB
Python
"""Shared domain exception classes used across routers and services."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
class JailNotFoundError(Exception):
|
|
"""Raised when a requested jail name does not exist."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Jail not found: {name!r}")
|
|
|
|
|
|
class JailOperationError(Exception):
|
|
"""Raised when a fail2ban jail operation fails."""
|
|
|
|
|
|
class ConfigValidationError(Exception):
|
|
"""Raised when config values fail validation before applying."""
|
|
|
|
|
|
class ConfigOperationError(Exception):
|
|
"""Raised when a config payload update or command fails."""
|
|
|
|
|
|
class ConfigDirError(Exception):
|
|
"""Raised when the fail2ban config directory is missing or inaccessible."""
|
|
|
|
|
|
class ConfigFileNotFoundError(Exception):
|
|
"""Raised when a requested config file does not exist."""
|
|
|
|
def __init__(self, filename: str) -> None:
|
|
"""Initialize with the filename that was not found.
|
|
|
|
Args:
|
|
filename: The filename that could not be located.
|
|
"""
|
|
self.filename = filename
|
|
super().__init__(f"Config file not found: {filename!r}")
|
|
|
|
|
|
class ConfigFileExistsError(Exception):
|
|
"""Raised when trying to create a file that already exists."""
|
|
|
|
def __init__(self, filename: str) -> None:
|
|
"""Initialize with the filename that already exists.
|
|
|
|
Args:
|
|
filename: The filename that conflicts.
|
|
"""
|
|
self.filename = filename
|
|
super().__init__(f"Config file already exists: {filename!r}")
|
|
|
|
|
|
class ConfigFileWriteError(Exception):
|
|
"""Raised when a file cannot be written (permissions, disk full, etc.)."""
|
|
|
|
|
|
class ConfigFileNameError(Exception):
|
|
"""Raised when a supplied filename is invalid or unsafe."""
|
|
|
|
|
|
class ServerOperationError(Exception):
|
|
"""Raised when a server control command (e.g. refresh) fails."""
|
|
|
|
|
|
class Fail2BanConnectionError(Exception):
|
|
"""Raised when the fail2ban socket is unreachable or returns an error."""
|
|
|
|
def __init__(self, message: str, socket_path: str) -> None:
|
|
"""Initialize with a human-readable message and the socket path.
|
|
|
|
Args:
|
|
message: Description of the connection problem.
|
|
socket_path: The fail2ban socket path that was targeted.
|
|
"""
|
|
self.socket_path: str = socket_path
|
|
super().__init__(f"{message} (socket: {socket_path})")
|
|
|
|
|
|
class Fail2BanProtocolError(Exception):
|
|
"""Raised when the response from fail2ban cannot be parsed."""
|
|
|
|
|
|
class FilterInvalidRegexError(Exception):
|
|
"""Raised when a regex pattern fails to compile."""
|
|
|
|
def __init__(self, pattern: str, error: str) -> None:
|
|
"""Initialize with the invalid pattern and compile error."""
|
|
self.pattern = pattern
|
|
self.error = error
|
|
super().__init__(f"Invalid regex {pattern!r}: {error}")
|
|
|
|
|
|
class JailNotFoundInConfigError(Exception):
|
|
"""Raised when the requested jail name is not defined in any config file."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Jail not found in config: {name!r}")
|
|
|
|
|
|
class ConfigWriteError(Exception):
|
|
"""Raised when writing a configuration file modification fails."""
|
|
|
|
def __init__(self, message: str) -> None:
|
|
self.message = message
|
|
super().__init__(message)
|
|
|
|
|
|
class JailNameError(Exception):
|
|
"""Raised when a jail name contains invalid characters."""
|
|
|
|
|
|
class JailAlreadyActiveError(Exception):
|
|
"""Raised when trying to activate a jail that is already active."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Jail is already active: {name!r}")
|
|
|
|
|
|
class JailAlreadyInactiveError(Exception):
|
|
"""Raised when trying to deactivate a jail that is already inactive."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Jail is already inactive: {name!r}")
|
|
|
|
|
|
class FilterNotFoundError(Exception):
|
|
"""Raised when the requested filter name is not found."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Filter not found: {name!r}")
|
|
|
|
|
|
class FilterAlreadyExistsError(Exception):
|
|
"""Raised when trying to create a filter whose `.conf` or `.local` already exists."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Filter already exists: {name!r}")
|
|
|
|
|
|
class FilterNameError(Exception):
|
|
"""Raised when a filter name contains invalid characters."""
|
|
|
|
|
|
class FilterReadonlyError(Exception):
|
|
"""Raised when trying to delete a shipped `.conf` filter with no `.local` override."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(
|
|
f"Filter {name!r} is a shipped default (.conf only); only user-created .local files can be deleted."
|
|
)
|
|
|
|
|
|
class ActionNotFoundError(Exception):
|
|
"""Raised when the requested action name is not found."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Action not found: {name!r}")
|
|
|
|
|
|
class ActionAlreadyExistsError(Exception):
|
|
"""Raised when trying to create an action whose `.conf` or `.local` already exists."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(f"Action already exists: {name!r}")
|
|
|
|
|
|
class ActionNameError(Exception):
|
|
"""Raised when an action name contains invalid characters."""
|
|
|
|
|
|
class ActionReadonlyError(Exception):
|
|
"""Raised when trying to delete a shipped `.conf` action with no `.local` override."""
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
super().__init__(
|
|
f"Action {name!r} is a shipped default (.conf only); only user-created .local files can be deleted."
|
|
)
|