Private
Public Access
Log every DM-email decision point (diagnostic follow-up to #66/#68)
A live "no emails arriving" report produced literally nothing in the logs, not even the SMTP-not-configured line -- this app has no logging config lowering the root level below Python's own WARNING default, so every .debug()/.info() call has been silently invisible in production all along. Bumped the SMTP-not-configured line to .warning, and added one at each early-return in _maybe_email_dm_notification (no other participant, recipient online, already has unread messages) plus a confirmation right before actually sending -- next attempt will show exactly which branch is being hit instead of nothing at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -221,7 +221,12 @@ async def send_email(
|
|||||||
"""
|
"""
|
||||||
cfg = await get_smtp_settings(db)
|
cfg = await get_smtp_settings(db)
|
||||||
if cfg is None:
|
if cfg is None:
|
||||||
logger.debug("SMTP not configured; skipping email to %s", to_address)
|
# WARNING, not .debug -- this app has no logging config lowering
|
||||||
|
# the root level below Python's own WARNING default, so anything
|
||||||
|
# below that is silently invisible in production (confirmed live:
|
||||||
|
# a real "no emails arriving" report produced nothing in the logs
|
||||||
|
# at all, this line included, even though it was relevant).
|
||||||
|
logger.warning("SMTP not configured; skipping email to %s", to_address)
|
||||||
return
|
return
|
||||||
palette = await _resolve_palette(db, theme_user)
|
palette = await _resolve_palette(db, theme_user)
|
||||||
html_body = _render_html(palette, subject, paragraphs, cta_label, cta_url)
|
html_body = _render_html(palette, subject, paragraphs, cta_label, cta_url)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from sqlalchemy import select, update
|
from sqlalchemy import select, update
|
||||||
@@ -16,6 +17,8 @@ from app.ws.focus_presence import FocusPresence
|
|||||||
from app.ws.global_presence import GlobalPresence
|
from app.ws.global_presence import GlobalPresence
|
||||||
from app.ws.presence import Presence
|
from app.ws.presence import Presence
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def _notify_offline_members(
|
async def _notify_offline_members(
|
||||||
db: AsyncSession,
|
db: AsyncSession,
|
||||||
@@ -168,6 +171,17 @@ async def _maybe_email_dm_notification(
|
|||||||
rooms.py's private _member_status (not importable from here), just
|
rooms.py's private _member_status (not importable from here), just
|
||||||
re-derived.
|
re-derived.
|
||||||
"""
|
"""
|
||||||
|
# #68 follow-up: this whole function used to have zero logging on any
|
||||||
|
# of its early-return paths, which made "why didn't an email go out"
|
||||||
|
# completely undiagnosable from the outside -- confirmed live, a real
|
||||||
|
# report of "no emails" produced nothing in the logs at all, not even
|
||||||
|
# at the level that turned out to be the actual cause. logger.warning
|
||||||
|
# (not .info/.debug) is deliberate: this app has no logging config
|
||||||
|
# setting the root level below Python's own WARNING default, so
|
||||||
|
# anything logged lower than that is silently invisible in production
|
||||||
|
# regardless of what it's actually about -- these aren't really
|
||||||
|
# warnings, they're the only level guaranteed to reach journalctl
|
||||||
|
# today.
|
||||||
room = await db.get(Room, room_id)
|
room = await db.get(Room, room_id)
|
||||||
if room is None or not room.is_dm:
|
if room is None or not room.is_dm:
|
||||||
return
|
return
|
||||||
@@ -179,14 +193,21 @@ async def _maybe_email_dm_notification(
|
|||||||
)
|
)
|
||||||
membership = result.scalar_one_or_none()
|
membership = result.scalar_one_or_none()
|
||||||
if membership is None:
|
if membership is None:
|
||||||
|
logger.warning("DM email skipped for room %s: no other participant found", room_id)
|
||||||
return
|
return
|
||||||
recipient = await db.get(User, membership.user_id)
|
recipient = await db.get(User, membership.user_id)
|
||||||
if recipient is None:
|
if recipient is None:
|
||||||
|
logger.warning(
|
||||||
|
"DM email skipped for room %s: recipient user %s not found", room_id, membership.user_id
|
||||||
|
)
|
||||||
return
|
return
|
||||||
# appear_offline is a manual "always look offline" override -- treated
|
# appear_offline is a manual "always look offline" override -- treated
|
||||||
# the same as genuinely offline here, same as everywhere else it's
|
# the same as genuinely offline here, same as everywhere else it's
|
||||||
# checked in this codebase.
|
# checked in this codebase.
|
||||||
if not recipient.appear_offline and await global_presence.is_online(recipient.id):
|
if not recipient.appear_offline and await global_presence.is_online(recipient.id):
|
||||||
|
logger.warning(
|
||||||
|
"DM email skipped for room %s: recipient %s is online", room_id, recipient.id
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Debounced to the first unread message in this conversation, not
|
# Debounced to the first unread message in this conversation, not
|
||||||
@@ -202,6 +223,11 @@ async def _maybe_email_dm_notification(
|
|||||||
.limit(1)
|
.limit(1)
|
||||||
)
|
)
|
||||||
if already_unread.scalar_one_or_none() is not None:
|
if already_unread.scalar_one_or_none() is not None:
|
||||||
|
logger.warning(
|
||||||
|
"DM email skipped for room %s: recipient %s already has unread messages",
|
||||||
|
room_id,
|
||||||
|
recipient.id,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if message.content:
|
if message.content:
|
||||||
@@ -211,6 +237,7 @@ async def _maybe_email_dm_notification(
|
|||||||
else:
|
else:
|
||||||
body_line = f"{sender.username} sent an image"
|
body_line = f"{sender.username} sent an image"
|
||||||
link = f"{base_url.rstrip('/')}/rooms/{room_id}"
|
link = f"{base_url.rstrip('/')}/rooms/{room_id}"
|
||||||
|
logger.warning("Sending DM email to %s for room %s", recipient.email, room_id)
|
||||||
await send_email(
|
await send_email(
|
||||||
db,
|
db,
|
||||||
recipient.email,
|
recipient.email,
|
||||||
|
|||||||
Reference in New Issue
Block a user