File size: 2,797 Bytes
0a367ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from __future__ import annotations

import logging
import traceback
from contextlib import asynccontextmanager
from pathlib import Path
from typing import AsyncGenerator

logger = logging.getLogger(__name__)


@asynccontextmanager
async def processing_error_handler(
    db_path: Path,
    notif_id: int,
    email_identifier: str,
    sender_email: str | None = None,
    subject: str | None = None,
    filename: str | None = None,
) -> AsyncGenerator[None, None]:
    """Catch any exception from the wrapped block, log the full stack trace,
    write an error_brief record to routing_results and daily_brief, then re-raise
    so the caller can set the appropriate final status."""
    try:
        yield
    except Exception as exc:
        tb = traceback.format_exc()
        logger.error(
            "Processing error [notif_id=%s, file=%s]: %s\n%s",
            notif_id, filename, exc, tb,
        )
        from app.database import get_db, insert_daily_brief, log_routing_result
        try:
            async with get_db(db_path) as conn:
                await log_routing_result(
                    conn,
                    notification_id=notif_id,
                    filename=filename,
                    doc_type=None,
                    action="error_brief",
                    email_identifier=email_identifier,
                    error_message=str(exc),
                )
                if sender_email is not None or subject is not None:
                    await insert_daily_brief(
                        conn,
                        email_identifier=email_identifier,
                        notification_id=notif_id,
                        sender_email=sender_email,
                        subject=subject,
                        filename=filename,
                        reason="error",
                        error_message=str(exc),
                    )
        except Exception as db_exc:
            logger.error(
                "processing_error_handler: DB write failed while recording error "
                "[notif_id=%s, file=%s]: %s",
                notif_id, filename, db_exc,
            )

        if sender_email is None and subject is None:
            from app.config import settings
            from app.lib.utils.notifier import send_developer_alert
            await send_developer_alert(
                settings,
                subject="[RCM] Processing error (no email context)",
                body=(
                    f"An exception occurred before sender/subject were available.\n\n"
                    f"notification_id: {notif_id}\n"
                    f"email_identifier: {email_identifier}\n"
                    f"filename: {filename}\n\n"
                    f"{tb}"
                ),
            )
        raise exc