fix: resolve pylint and type-checking issues

- Fix return type annotation in SetupRedirectMiddleware.dispatch() to use Response instead of RedirectResponse
- Replace broad 'except Exception' with specific exception types (FileNotFoundError, ValueError, OSError, etc.)
- Rename AppConfig.validate() to validate_config() to avoid shadowing BaseModel.validate()
- Fix ValidationResult.errors field to use List[str] with default_factory
- Add pylint disable comments for intentional broad exception catches during shutdown
- Rename lifespan parameter to _application to indicate unused variable
- Update all callers to use new validate_config() method name
This commit is contained in:
2025-12-13 20:29:07 +01:00
parent 63742bb369
commit 3cb644add4
5 changed files with 37 additions and 23 deletions

View File

@@ -43,8 +43,13 @@ from src.server.services.websocket_service import get_websocket_service
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Manage application lifespan (startup and shutdown)."""
async def lifespan(_application: FastAPI):
"""Manage application lifespan (startup and shutdown).
Args:
_application: The FastAPI application instance (unused but required
by the lifespan protocol).
"""
# Setup logging first with DEBUG level
logger = setup_logging(log_level="DEBUG")
@@ -72,8 +77,11 @@ async def lifespan(app: FastAPI):
)
# Sync anime_directory from config.json to settings
if config.other and config.other.get("anime_directory"):
settings.anime_directory = str(config.other["anime_directory"])
# config.other is Dict[str, object] - pylint doesn't infer this
other_settings = dict(config.other) if config.other else {}
if other_settings.get("anime_directory"):
anime_dir = other_settings["anime_directory"]
settings.anime_directory = str(anime_dir)
logger.info(
"Loaded anime_directory from config: %s",
settings.anime_directory
@@ -82,7 +90,7 @@ async def lifespan(app: FastAPI):
logger.debug(
"anime_directory not found in config.other"
)
except Exception as e:
except (OSError, ValueError, KeyError) as e:
logger.warning("Failed to load config from config.json: %s", e)
# Initialize progress service with event subscription
@@ -131,7 +139,7 @@ async def lifespan(app: FastAPI):
"Download service initialization skipped - "
"anime directory not configured"
)
except Exception as e:
except (OSError, RuntimeError, ValueError) as e:
logger.warning("Failed to initialize download service: %s", e)
# Continue startup - download service can be initialized later
@@ -152,12 +160,14 @@ async def lifespan(app: FastAPI):
# Shutdown download service and its thread pool
try:
from src.server.services.download_service import _download_service_instance
from src.server.services.download_service import ( # noqa: E501
_download_service_instance,
)
if _download_service_instance is not None:
logger.info("Stopping download service...")
await _download_service_instance.stop()
logger.info("Download service stopped successfully")
except Exception as e:
except Exception as e: # pylint: disable=broad-exception-caught
logger.error("Error stopping download service: %s", e, exc_info=True)
# Close database connections
@@ -165,7 +175,7 @@ async def lifespan(app: FastAPI):
from src.server.database.connection import close_db
await close_db()
logger.info("Database connections closed")
except Exception as e:
except Exception as e: # pylint: disable=broad-exception-caught
logger.error("Error closing database: %s", e, exc_info=True)
logger.info("FastAPI application shutdown complete")