Closes #170: Errorhandling and structured logging#236
Closes #170: Errorhandling and structured logging#236KodeSage wants to merge 1 commit intoSolFoundry:mainfrom
Conversation
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis pull request implements centralized error handling and structured logging infrastructure for the backend. It introduces audit logging calls to authentication, bounty, and payout endpoints; creates new core modules for audit trail tracking, correlation ID propagation, exception handling, and logging configuration; updates the health check endpoint to include service dependency status; and adds comprehensive test coverage for all new components. The changes are integrated into the main application via middleware registration and exception handler setup. Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Reason: PR description is empty or too short (< 20 chars) If you believe this is an error, please fix and reopen. SolFoundry Review Bot |
Description
Closes #170
Implements centralized error handling and structured logging across the entire SolFoundry backend. Every API error, webhook event, and payout action is now traceable via correlation IDs and structured JSON logs.
What's included:
Core Infrastructure (
backend/app/core/)logging_config.py— Structured JSON logging with 4 separate log streams (application, access, error, audit), rotating file handlers, and configurable retention policycorrelation.py— Correlation ID middleware that assigns/propagatesX-Correlation-IDheaders viacontextvarsfor distributed request tracingexceptions.py— Global exception handlers forHTTPException,RequestValidationError, and unhandled exceptions — all return structured JSON responses with{error: {code, message, correlation_id, details}}audit.py— Dedicated audit logger for sensitive operations (payouts, auth, bounty state changes, webhooks)Enhanced Health Check
/healthendpoint now reports dependency status for Database and Redis withhealthy/degraded/unhealthystatesAudit Trail Coverage
Configuration (all via environment variables)
LOG_DIR— log output directory (default:logs/)LOG_LEVEL— root log level (default:INFO)LOG_FORMAT—jsonortext(default:json)LOG_MAX_BYTES— rotation size per file (default: 10MB)LOG_BACKUP_COUNT— rotated file count (default: 5)LOG_RETENTION_DAYS— retention policy (default: 30 days)Tests — 40 new tests (unit + integration)
test_error_handling.py(8) — structured error responsestest_correlation.py(6) — correlation ID middlewaretest_logging_config.py(8) — JSON/text formatters, filters, setuptest_audit.py(5) — audit event emissiontest_health_check.py(7) — enhanced health endpointtest_middleware_integration.py(6) — end-to-end pipelineSolana Wallet for Payout
Wallet: EwWiRi5zkynTYN9pvgjqCEiWKuFwR7SLdgFox9R3GmyS
Type of Change
Checklist
console.logor debugging code left behindTesting
All 40 new tests pass. All 129 existing bounty tests pass with zero regressions. Pre-existing
test_payouts.py::TestValidation::test_invalid_wallet(previously broken by non-serializableValueErrorin validation errors) now also passes thanks to the_sanitize_errorsfix in the global exception handler.Structured JSON error response (404):
{ "error": { "code": 404, "message": "Bounty not found", "correlation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } }Structured JSON audit log entry:
{ "timestamp": "2026-03-21T00:10:35.498544+00:00", "level": "INFO", "logger": "solfoundry.audit", "message": "AUDIT payout.created payout/tx-abc123 by user=user-42", "correlation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "action": "payout.created", "resource_type": "payout", "resource_id": "tx-abc123", "user_id": "user-42", "details": {"recipient": "alice", "amount": 1000, "token": "FNDRY"} }Enhanced health check response:
{ "status": "healthy", "bounties": 42, "contributors": 15, "last_sync": "2026-03-21T00:05:00+00:00", "dependencies": { "database": {"status": "healthy"}, "redis": {"status": "healthy"} } }Additional Notes
from __future__ import annotationsandtyping.Optionalinstead ofX | Nonesyntax)backend/app/api/webhooks/github.py(str | None→Optional[str])propagate = Falsefor access and audit loggers to prevent duplicate entries in the root logger_sanitize_errorsutility in the exception handler converts non-JSON-serializable objects (likeValueErrorinstances in Pydantic validation contexts) to strings, fixing a latent buglogging,logging.handlers,contextvars,uuid,json)@chronoeth-creator, this is completed!