Merge pull request #830 from christianlouis/copilot/fix-try-except-pass-issues
fix(main): log exceptions in shutdown handlers instead of silently swallowing them
This commit is contained in:
+19
-2
@@ -27,7 +27,21 @@ RUN pip install --no-cache-dir -r requirements.txt \
|
|||||||
&& find /opt/venv -type f -name "*.pyc" -delete \
|
&& find /opt/venv -type f -name "*.pyc" -delete \
|
||||||
&& find /opt/venv -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
&& find /opt/venv -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
|
||||||
# ── Stage 2: Documentation builder ──────────────────────────────────────────
|
# ── Stage 2: Frontend asset builder ─────────────────────────────────────────
|
||||||
|
# Compiles Tailwind CSS (a devDependency) into the minified styles.css.
|
||||||
|
# npm ci installs ALL deps (including devDependencies) so the tailwindcss CLI
|
||||||
|
# is available; using --omit=dev would cause 'tailwindcss: not found'.
|
||||||
|
FROM node:20-slim AS frontend-builder
|
||||||
|
|
||||||
|
WORKDIR /frontend
|
||||||
|
|
||||||
|
COPY frontend/package.json frontend/package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY frontend/ ./
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ── Stage 4: Documentation builder ──────────────────────────────────────────
|
||||||
FROM python:3.14.3-slim AS docs-builder
|
FROM python:3.14.3-slim AS docs-builder
|
||||||
|
|
||||||
WORKDIR /docs
|
WORKDIR /docs
|
||||||
@@ -43,7 +57,7 @@ COPY mkdocs.yml /docs/mkdocs.yml
|
|||||||
# Build the static documentation site
|
# Build the static documentation site
|
||||||
RUN mkdocs build --config-file /docs/mkdocs.yml --site-dir /docs/docs_build
|
RUN mkdocs build --config-file /docs/mkdocs.yml --site-dir /docs/docs_build
|
||||||
|
|
||||||
# ── Stage 3: Runtime image ───────────────────────────────────────────────────
|
# ── Stage 5: Runtime image ───────────────────────────────────────────────────
|
||||||
FROM python:3.14.3-slim
|
FROM python:3.14.3-slim
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
@@ -81,6 +95,9 @@ COPY ./RUNTIME_INFO /app/RUNTIME_INFO
|
|||||||
# Copy the pre-built MkDocs documentation site (served at /help)
|
# Copy the pre-built MkDocs documentation site (served at /help)
|
||||||
COPY --from=docs-builder /docs/docs_build /app/docs_build
|
COPY --from=docs-builder /docs/docs_build /app/docs_build
|
||||||
|
|
||||||
|
# Copy the compiled Tailwind CSS (built in the frontend-builder stage)
|
||||||
|
COPY --from=frontend-builder /frontend/static/styles.css /app/frontend/static/styles.css
|
||||||
|
|
||||||
# Create necessary runtime directories in a single layer
|
# Create necessary runtime directories in a single layer
|
||||||
RUN mkdir -p /app/runtime_info /workdir
|
RUN mkdir -p /app/runtime_info /workdir
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -399,11 +399,11 @@ async def list_dropbox_folders(
|
|||||||
async def save_dropbox_settings(
|
async def save_dropbox_settings(
|
||||||
request: Request,
|
request: Request,
|
||||||
refresh_token: Annotated[str, Form(...)],
|
refresh_token: Annotated[str, Form(...)],
|
||||||
|
_admin: AdminUser,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
app_key: Annotated[Optional[str], Form()] = None,
|
app_key: Annotated[Optional[str], Form()] = None,
|
||||||
app_secret: Annotated[Optional[str], Form()] = None,
|
app_secret: Annotated[Optional[str], Form()] = None,
|
||||||
folder_path: Annotated[Optional[str], Form()] = None,
|
folder_path: Annotated[Optional[str], Form()] = None,
|
||||||
_admin: AdminUser = Depends(_require_admin),
|
|
||||||
db: Session = Depends(get_db),
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Save Dropbox settings to database (primary) and .env file (best-effort).
|
Save Dropbox settings to database (primary) and .env file (best-effort).
|
||||||
|
|||||||
@@ -376,12 +376,12 @@ def format_time_remaining(time_delta):
|
|||||||
async def save_google_drive_settings(
|
async def save_google_drive_settings(
|
||||||
request: Request,
|
request: Request,
|
||||||
refresh_token: Annotated[str, Form(...)],
|
refresh_token: Annotated[str, Form(...)],
|
||||||
|
_admin: AdminUser,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
client_id: Annotated[Optional[str], Form()] = None,
|
client_id: Annotated[Optional[str], Form()] = None,
|
||||||
client_secret: Annotated[Optional[str], Form()] = None,
|
client_secret: Annotated[Optional[str], Form()] = None,
|
||||||
folder_id: Annotated[Optional[str], Form()] = None,
|
folder_id: Annotated[Optional[str], Form()] = None,
|
||||||
use_oauth: Annotated[str, Form()] = "true",
|
use_oauth: Annotated[str, Form()] = "true",
|
||||||
_admin: AdminUser = Depends(_require_admin),
|
|
||||||
db: Session = Depends(get_db),
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Save Google Drive settings to the .env file (best-effort) and persist to database.
|
Save Google Drive settings to the .env file (best-effort) and persist to database.
|
||||||
|
|||||||
+2
-2
@@ -316,12 +316,12 @@ def format_time_remaining(time_delta):
|
|||||||
async def save_onedrive_settings(
|
async def save_onedrive_settings(
|
||||||
request: Request,
|
request: Request,
|
||||||
refresh_token: Annotated[str, Form(...)],
|
refresh_token: Annotated[str, Form(...)],
|
||||||
|
_admin: AdminUser,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
client_id: Annotated[Optional[str], Form()] = None,
|
client_id: Annotated[Optional[str], Form()] = None,
|
||||||
client_secret: Annotated[Optional[str], Form()] = None,
|
client_secret: Annotated[Optional[str], Form()] = None,
|
||||||
tenant_id: Annotated[str, Form()] = "common",
|
tenant_id: Annotated[str, Form()] = "common",
|
||||||
folder_path: Annotated[Optional[str], Form()] = None,
|
folder_path: Annotated[Optional[str], Form()] = None,
|
||||||
_admin: AdminUser = Depends(_require_admin),
|
|
||||||
db: Session = Depends(get_db),
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Saves to database (primary) and .env file (best-effort).
|
Saves to database (primary) and .env file (best-effort).
|
||||||
|
|||||||
+2
-2
@@ -297,13 +297,13 @@ async def lifespan(app: FastAPI):
|
|||||||
try:
|
try:
|
||||||
logging.info("Application shutting down")
|
logging.info("Application shutting down")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # noqa: S110
|
_startup_logger.exception("Error during shutdown logging")
|
||||||
|
|
||||||
# Send shutdown notification
|
# Send shutdown notification
|
||||||
try:
|
try:
|
||||||
notify_shutdown()
|
notify_shutdown()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # noqa: S110
|
_startup_logger.exception("Error sending shutdown notification")
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
|
|||||||
Reference in New Issue
Block a user