Skip to content

Conversation

@KyleTryon
Copy link
Contributor

What Was Broken

  • ❌ No HTTP-level tracing middleware
  • ❌ tRPC Sentry middleware using wrong import
  • ❌ tRPC middleware only on publicProcedure
  • ❌ honoIntegration not explicitly configured

What's Fixed

  • ✅ HTTP tracing middleware added to Hono
  • ✅ tRPC middleware uses @/utils/sentry (build-time aliased)
  • ✅ tRPC middleware applied to base procedure (all procedures inherit)
  • ✅ honoIntegration explicitly configured
  • ✅ Complete trace visibility for all operations

@KyleTryon KyleTryon requested a review from Copilot January 12, 2026 17:21
Comment on lines +68 to +72
const baseProcedure = (() => {
// Check if Sentry has trpcMiddleware (available in Cloudflare and Node.js)
if (typeof Sentry.trpcMiddleware === "function") {
const sentryMiddleware = t.middleware(
Sentry.trpcMiddleware({

This comment was marked as outdated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For testing purposes: This was an auto-detected error by Sentry. Not automatically triggered.

Copy link
Contributor Author

@KyleTryon KyleTryon Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude response validates issue:

Why This Happened

I created baseProcedure and exported it as publicProcedure for "compatibility", but forgot to update the >downstream procedure definitions. They're still chaining from t.procedure instead of baseProcedure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result: ALL procedures now have Sentry tracing! The Sentry bot saved us from deploying a "fix" that would have done almost nothing. 🙏

Deploy and test - you should now see traces for feed subscriptions and all other operations!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a big issue Claude code left behind by mistake. It nearly got it right, but dropepd the ball at the end. Somewhat expected. Good example of a really important catch by Seer.

@KyleTryon
Copy link
Contributor Author

After fixing the Sentry bot request, I am still currently waiting on Copilot. I feel like it is normally faster, but Seer was much faster in this run. I am now going to trigger Seer manually.

@sentry review

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Sentry integration for the Hono-based API by adding HTTP-level tracing middleware and properly configuring tRPC middleware to use build-time aliased imports. It also explicitly configures Sentry integrations (Hono, console logging) and enables structured logging capabilities.

Changes:

  • Added HTTP tracing middleware to Hono that creates spans for all HTTP requests with proper transaction names and attributes
  • Refactored tRPC Sentry middleware to use build-time aliased @/utils/sentry import instead of dynamic @sentry/cloudflare import
  • Explicitly configured honoIntegration() and consoleLoggingIntegration() in both Node.js and Cloudflare entry points
  • Enabled sendDefaultPii: true in Sentry config for better context (with existing PII filtering)
  • Added documentation for Sentry structured logging with examples of log levels and parameterized logs

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/api/src/trpc/init.ts Refactored to use build-time aliased Sentry import; middleware now applied to baseProcedure which is exported as publicProcedure
packages/api/src/hono/app.ts Added HTTP tracing middleware that creates spans for all HTTP requests with method, path, URL, and status code attributes
packages/api/src/entries/node.ts Added consoleLoggingIntegration and honoIntegration to Sentry initialization
packages/api/src/entries/cloudflare.ts Added consoleLoggingIntegration and honoIntegration to Sentry configuration
packages/api/src/config/sentry.ts Enabled sendDefaultPii for better error context (safe due to existing beforeSend PII filtering)
docs/architecture/sentry-integration.md Added documentation for structured logging including log levels, parameterized logs, and viewing logs in Sentry UI

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 67 to 74
async () => {
await next();

// Add response status to span
const currentSpan = Sentry.getActiveSpan?.();
if (currentSpan) {
currentSpan.setAttribute("http.status_code", c.res.status);
}
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback receives a span parameter from Sentry.startSpan() that can be used directly. Instead of calling Sentry.getActiveSpan?.() and checking if it exists, use the span parameter. This simplifies the code and avoids dependency on getActiveSpan which may not be available in all Sentry implementations. Change the callback signature from async () => to async (span) => and then directly call span.setAttribute("http.status_code", c.res.status) after the await next() call.

Suggested change
async () => {
await next();
// Add response status to span
const currentSpan = Sentry.getActiveSpan?.();
if (currentSpan) {
currentSpan.setAttribute("http.status_code", c.res.status);
}
async (span) => {
await next();
// Add response status to span
span.setAttribute("http.status_code", c.res.status);

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot is correct.

✅ Good catch! You're absolutely right.

Using the span parameter is the recommended pattern per Sentry documentation.

Benefits:

  • Simpler code (no optional chaining or null checks)
  • Direct reference to the span being created (safer than querying global state)
  • Guaranteed to be provided by startSpan() callback

Fixed in commit f39d4a8.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was likely to work, but was definiately written incorrectly and I assume based on outdated examples in the LLM. Copilot caught it. Claude was able to verify it using the docs we already had loaded in context (did not reach out to mcp, but didnt need to).

Use the span parameter provided by Sentry.startSpan() callback instead
of calling getActiveSpan(). This is the recommended pattern per Sentry
documentation and provides several benefits:

- Simpler code (no optional chaining or null checks needed)
- More explicit (direct reference to the span being created)
- Safer (avoids potential issues with nested spans in complex scenarios)
- Better compatibility (span parameter is guaranteed to be provided)

References:
- https://docs.sentry.io/platforms/javascript/guides/cloudflare/performance/instrumentation/custom-instrumentation/
- https://docs.sentry.io/platforms/javascript/guides/node/performance/instrumentation/custom-instrumentation/

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@KyleTryon KyleTryon merged commit d5597c8 into main Jan 12, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants