This commit is contained in:
Bastian Wagner
2026-08-15 21:05:55 +02:00
parent 420d089760
commit adfe14dfa8
2 changed files with 67 additions and 11 deletions

View File

@@ -79,6 +79,20 @@ class SyncManager:
def _notify_action_required(self, session: Any, user: Any, message: str | None) -> None:
if self.notifier is None or not user.notify_email_enabled or not user.notification_email:
return
# A notifier with no SMTP host configured silently no-ops in send()
# rather than raising -- without this check, that silence would look
# identical to "everything's fine" in the system log, leaving an
# opted-in user with no way to find out why no mail ever arrives.
if not getattr(self.notifier, "configured", True):
self._record_log(
session,
(
f"Skipped action-required email to {user.notification_email} for user {user.id} "
f"({user.name}): SMTP is not configured (SMTP_HOST unset)."
),
user_id=user.id,
)
return
try:
self.notifier.send(
to_address=user.notification_email,
@@ -89,17 +103,20 @@ class SyncManager:
logger.warning(
"sync_user: failed to send action-required notification for user %s", user.id, exc_info=True
)
try:
SystemLogRepository(session).add(
source="email_notification",
message=(
f"Failed to email {user.notification_email} for user {user.id} ({user.name}): "
f"{type(exc).__name__}: {exc}"
),
user_id=user.id,
)
except Exception:
logger.warning("sync_user: failed to record email-notification failure in system log", exc_info=True)
self._record_log(
session,
(
f"Failed to email {user.notification_email} for user {user.id} ({user.name}): "
f"{type(exc).__name__}: {exc}"
),
user_id=user.id,
)
def _record_log(self, session: Any, message: str, *, user_id: int | None = None) -> None:
try:
SystemLogRepository(session).add(source="email_notification", message=message, user_id=user_id)
except Exception:
logger.warning("sync_user: failed to record email-notification entry in system log", exc_info=True)
async def _lock_for(self, user_id: int) -> asyncio.Lock:
async with self._locks_guard: