rmi-backend/app/api/v1/admin/glitchtip_test.py

60 lines
2.1 KiB
Python

"""T07 GlitchTip test endpoint.
POST /api/v1/_test/glitchtip
{"type": "error", "message": "test error"}
POST /api/v1/_test/exception
→ triggers a real exception, captured by GlitchTip
POST /api/v1/_test/message
→ captures an info-level message
Used for:
- Verifying the GlitchTip pipeline works
- Smoke testing after deploys
- Demonstrating the secret-scrubbing before_send hook
"""
from __future__ import annotations
import logging
from fastapi import APIRouter
from pydantic import BaseModel
log = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1/_test", tags=["test"])
class GlitchtipTestRequest(BaseModel):
type: str = "error" # error | exception | message
message: str = "test event from RMI"
secret: str | None = None # should be REDACTED in Sentry
@router.post("/glitchtip")
async def test_glitchtip(req: GlitchtipTestRequest) -> dict:
"""Trigger a test event. Tests the secret-scrubbing before_send hook."""
if req.type == "exception":
try:
raise ValueError(req.message)
except Exception as e:
try:
from app.core.observability import capture_exception
capture_exception(e, secret=req.secret, route="/api/v1/_test/glitchtip")
except ImportError:
log.exception("test_exception_no_sentry")
return {"captured": "exception", "message": req.message}
if req.type == "message":
try:
from app.core.observability import capture_message
capture_message(req.message, level="warning", secret=req.secret)
except ImportError:
log.warning(f"test_message_no_sentry: {req.message}")
return {"captured": "message", "message": req.message}
# default: error log + capture
log.error(f"test_error: {req.message} (secret={req.secret})")
try:
from app.core.observability import capture_message
capture_message(req.message, level="error", secret=req.secret)
except ImportError:
pass
return {"captured": "error", "message": req.message, "secret_redacted_in_sentry": True}