Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions weekly_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,14 +492,29 @@ def _finalize(
duration,
)

# Send completion email (non-blocking)
# Send completion email.
# send_step_email never raises (see emailer.py docstring) — it returns
# True/False. The old try/except was dead code, AND the False return
# was being silently dropped. If Gmail SMTP AND SES both fail, the
# caller needs to know so monitoring isn't blind to a successful run
# that silently had no notification.
if not dry_run and only is None:
try:
from emailer import send_step_email
step_name = f"Data Phase {phase}" if phase else "Data Collection"
send_step_email(step_name, results, run_date)
except Exception as exc:
logger.warning("Step email failed (non-fatal): %s", exc)
from emailer import send_step_email
step_name = f"Data Phase {phase}" if phase else "Data Collection"
sent = send_step_email(step_name, results, run_date)
if not sent:
# Log at ERROR so CloudWatch alarms (if wired to ERROR-level)
# surface the missed email. Not raising because the data
# collection itself succeeded — only monitoring is affected.
# Downstream Step Function steps can still consume the S3 output.
logger.error(
"Step email '%s' failed to send — both Gmail SMTP and SES "
"fallback returned failure. Monitoring will be blind to "
"this run's result summary. Check EMAIL_SENDER, "
"EMAIL_RECIPIENTS, GMAIL_APP_PASSWORD env vars and SES "
"identity verification.",
step_name,
)


def _write_manifest(bucket: str, s3_prefix: str, run_date: str, results: dict) -> None:
Expand Down
Loading