feat: integrate Sentry for global error monitoring#157
Conversation
…protocol#48) Adds Sentry error monitoring to the TrustFlow backend API: - SentryService (@global): initialises Sentry.init() on bootstrap when SENTRY_DSN env var is present; no-ops silently in dev/test without a DSN. Exposes captureException() and captureMessage() for programmatic use. - SentryExceptionFilter (global): catches every unhandled exception. 4xx HttpExceptions are returned normally; 5xx and non-HTTP exceptions are captured to Sentry with request URL/method/IP context before the error response is sent. - process.on('unhandledRejection') and process.on('uncaughtException') handlers in main.ts: forward async and sync crashes to Sentry before the process exits, ensuring no silent failures on production. - Swagger description updated to document the Sentry requirement (SENTRY_DSN env var). - tsconfig.eslint.json: extends tsconfig.json without excluding *.spec.ts so ESLint can parse spec files correctly; updates .eslintrc.js to use it. - Tests: 18 passing unit tests for SentryService (init, captureException, captureMessage, isInitialized) and SentryExceptionFilter (4xx no-capture, 5xx capture, unknown exceptions, response shape). - npm run lint: auto-fixed prettier formatting across existing source files.
meshackyaro
left a comment
There was a problem hiding this comment.
Fix pipeline. All checks are failing
… explicit SENTRY_DSN='' for no-DSN path
|
updated the CI workflow to go with this PR main changes:
|
|
Please review @meshackyaro |
Thanks for your contribution! The CI checks aren't running properly because your branch has an outdated version of the workflow file. The workflow configuration has been updated in main since you created this branch. To fix this, please sync your branch with the latest main: Fetch the latest changesgit fetch origin Merge main into your branchgit merge origin/main Resolve any conflicts if they appear, then pushgit push Alternatively, if you prefer rebasing: Once you push the updated branch, the CI checks should run properly: Let me know if you run into any issues! |
…n CI - Add @stellar/stellar-sdk to dependencies (was imported but missing from package.json) - Replace SorobanRpc import alias with rpc (renamed in stellar-sdk v16) - Export HealthStatus interface so tsc can name it in public method signatures - Remove invalid 'required: false' from Swagger property schema (not valid JSON Schema)
|
Thanks for the PR! I like the consolidated workflow approach - it's cleaner and more efficient than the current three-job setup. Now, the CI is failing and needs a couple of fixes:
The test in discord.service.spec.ts expects a warning when the webhook URL is missing, but that's not matching actual behavior. Since we intentionally don't have the webhook configured, please adjust the test to reflect what actually happens.
You've set coverage requirements to 50% across the board. Since we're still in early development, please revert these to 0 to match main: "coverageThreshold": { We'll tighten these up as the codebase matures. Meanwhile, well done on the job done so far! |
process.env.X = undefined sets the string 'undefined' rather than deleting the var. When originalEnv is undefined (env var was not set), subsequent beforeEach calls construct DiscordService with this.webhookUrl = 'undefined' (truthy), causing the 'not configured' check to be skipped and the test to fail with 0 warn calls. Use delete process.env.DISCORD_WEBHOOK_URL when originalEnv is undefined to properly clean up between tests.
|
Fixed the CI failure. Root cause: Why it only surfaced now: this PR correctly fixed the CI test glob to include Fix: use |
The 50% threshold set in the initial commit assumed full coverage of the codebase, but only the new Sentry and Discord service files have tests. Lower threshold to 10% to unblock CI while the rest of the test suite is built out.
Good job getting this done and Well done! |
Closes #48
What changed
src/sentry/sentry.service.ts—@Global()NestJS service that wrapsSentry.init(). Initialises only whenSENTRY_DSNis set; safely no-ops in dev/test without one. ExposescaptureException(exception, context?)andcaptureMessage(message, level).src/sentry/sentry.module.ts— Global module soSentryServiceis available anywhere in the app without explicit imports.src/common/filters/sentry-exception.filter.ts—@Catch()global filter that intercepts every unhandled exception:HttpException→ returned as-is, not captured (client errors, not actionable).HttpException→ captured to Sentry with request URL/method/IP context.500 Internal server error.src/main.ts— Two process-level handlers registered beforebootstrap():This ensures async crashes that escape NestJS are still sent to Sentry before the process dies.
src/app.module.ts— ImportsSentryModulefirst so the service is available at bootstrap.Swagger — Description updated to document the
SENTRY_DSNrequirement.tsconfig.eslint.json+.eslintrc.js— Fixed pre-existing ESLintparserOptions.projecterror that caused all*.spec.tsfiles insrc/to be unparseable; now uses a dedicatedtsconfig.eslint.jsonthat includes spec files without polluting the production build.Why
Unhandled rejections and uncaught exceptions were silently swallowed on production. This PR wires every error path — global filter, process events — into Sentry so the team gets real-time alerts and full stack traces.
How to test
SENTRY_DSN=<your-dsn>andNODE_ENV=productionin.envnpm run dev— verify log line:🔍 Sentry error monitoring activeSENTRY_DSNset — app starts normally with a warning; no Sentry calls made