Skip to content

feat(core): Add Supabase Queues support #15921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

onurtemizkan
Copy link
Collaborator

@onurtemizkan onurtemizkan commented Mar 28, 2025

Resolves: #14611

Summary:

Sample Queue Event: Link

  • Adds queue spans and breadcrumbs for Supabase Queue operations.
    • Usage with supabaseClient.rpc('<queue_op>', ...)
    • Usage with supabaseClient.schema(...).rpc('queue_op', ...)
  • Mapped operations to their respective op names documented here
    • producer ops: send, send_batch
    • consumer op: pop
  • Added browser integration tests, and e2e tests.

Copy link
Contributor

github-actions bot commented Mar 28, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.16 kB - -
@sentry/browser - with treeshaking flags 22.73 kB - -
@sentry/browser (incl. Tracing) 39.87 kB - -
@sentry/browser (incl. Tracing, Replay) 77.99 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 67.83 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 82.69 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 94.79 kB - -
@sentry/browser (incl. Feedback) 40.83 kB - -
@sentry/browser (incl. sendFeedback) 28.81 kB - -
@sentry/browser (incl. FeedbackAsync) 33.7 kB - -
@sentry/react 25.88 kB - -
@sentry/react (incl. Tracing) 41.86 kB - -
@sentry/vue 28.64 kB - -
@sentry/vue (incl. Tracing) 41.69 kB - -
@sentry/svelte 24.18 kB - -
CDN Bundle 25.66 kB - -
CDN Bundle (incl. Tracing) 39.76 kB - -
CDN Bundle (incl. Tracing, Replay) 75.82 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 81.27 kB - -
CDN Bundle - uncompressed 74.96 kB - -
CDN Bundle (incl. Tracing) - uncompressed 117.59 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 231.88 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 244.48 kB - -
@sentry/nextjs (client) 43.89 kB - -
@sentry/sveltekit (client) 40.32 kB - -
@sentry/node-core 47.99 kB -0.01% -1 B 🔽
@sentry/node 147.03 kB - -
@sentry/node - without tracing 92.24 kB - -
@sentry/aws-serverless 103.67 kB - -

View base workflow run

@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from bbadd60 to e7b3370 Compare March 31, 2025 09:44
@onurtemizkan onurtemizkan force-pushed the onur/supabase-integration branch from 1bc2897 to d387514 Compare March 31, 2025 10:26
@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from e7b3370 to 56a2d84 Compare March 31, 2025 14:12
@onurtemizkan onurtemizkan linked an issue Mar 31, 2025 that may be closed by this pull request
@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from 56a2d84 to 13d60e0 Compare March 31, 2025 14:25
@onurtemizkan onurtemizkan force-pushed the onur/supabase-integration branch 4 times, most recently from 423397d to 556703c Compare April 14, 2025 15:26
Base automatically changed from onur/supabase-integration to develop April 17, 2025 13:35
@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from 13d60e0 to 74869e4 Compare April 22, 2025 14:16
@onurtemizkan onurtemizkan marked this pull request as ready for review April 24, 2025 09:32
@onurtemizkan onurtemizkan requested review from lforst and smeubank April 24, 2025 09:33
@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from e63915a to 719c8b6 Compare April 24, 2025 14:11
},
},
async span => {
return (Reflect.apply(target, thisArg, argumentsList) as Promise<unknown>).then((res: unknown) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably also end the span when it throws/rejects? We can also set the status of the span then.

name: 'supabase.db.rpc',
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.supabase',
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can add the messaging.system attribute to be 'supabase' as described in https://develop.sentry.dev/sdk/telemetry/traces/modules/queues/

Comment on lines 238 to 239
const isProducerSpan = argumentsList[0] === 'enqueue';
const isConsumerSpan = argumentsList[0] === 'dequeue';
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know if this recently changed, but here they show send and pop as rpc args: https://supabase.com/docs/guides/queues/quickstart#enqueueing-and-dequeueing-messages 🤔

@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch 4 times, most recently from fb8eeb1 to a8da234 Compare May 31, 2025 20:58
@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch 2 times, most recently from ff2f804 to 5ce5ee9 Compare June 23, 2025 15:58
@onurtemizkan onurtemizkan requested review from Lms24 and AbhiPrasad June 23, 2025 23:39
@AbhiPrasad
Copy link
Member

@sentry review

Copy link

On it! We are reviewing the PR and will provide feedback shortly.

Copy link

PR Description

This pull request introduces instrumentation for Supabase queue operations using pgmq, enabling Sentry to capture spans and breadcrumbs for queue publishing and processing. This provides visibility into asynchronous task execution within Supabase applications.

Click to see more

Key Technical Changes

The key technical changes include: 1) Instrumenting the rpc method of the Supabase client to detect queue operations (send, send_batch, pop). 2) Creating spans for queue publish and process operations, capturing relevant metadata like queue name and message ID. 3) Adding breadcrumbs for queue operations to provide context in Sentry events. 4) Modifying queue messages to inject Sentry trace context for distributed tracing. 5) Adding e2e tests to verify the instrumentation in a Next.js application.

Architecture Decisions

The primary architectural decision involves using Proxy objects to intercept calls to the Supabase client's rpc method and the schema(...).rpc(...) method. This allows for non-intrusive instrumentation without modifying the Supabase client's core code. The trace context is injected directly into the message body to propagate tracing information across queue operations.

Dependencies and Interactions

This integration depends on the @supabase/supabase-js library and interacts with Sentry's tracing and breadcrumb APIs. It also relies on the pgmq extension being enabled in the Supabase database. The integration injects Sentry trace context into queue messages, which requires consumers to be instrumented to extract and continue the trace.

Risk Considerations

Potential risks include: 1) Performance overhead due to the instrumentation, although proxies are generally performant. 2) Incorrectly identifying queue operations, leading to spurious spans. 3) Failure to propagate trace context if consumers are not properly instrumented. 4) Security implications of modifying message bodies, although the injected data is limited to Sentry trace context. 5) The modification of the arguments list in place could lead to unexpected side effects.

Notable Implementation Details

Notable implementation details include: 1) The use of continueTrace to link consumer spans to producer spans. 2) The handling of both rpc and schema(...).rpc(...) calls. 3) The injection of Sentry trace context into the message body. 4) The vendoring of SQL code from the Supabase repository to enable queue access locally.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from 4f19854 to 1c518a2 Compare July 3, 2025 14:40
cursor[bot]

This comment was marked as outdated.

@smeubank
Copy link
Member

anybody got eyes on this anymore? 😅

@onurtemizkan onurtemizkan force-pushed the onur/supabase-queues branch from 1c518a2 to 327b57a Compare July 24, 2025 11:29
cursor[bot]

This comment was marked as outdated.

});
},
);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Supabase RPC Error Handling Flaws

The instrumentRpcConsumer and instrumentRpcProducer functions throw a TypeError when computing messageId. This occurs because res?.data?.map(...).join(',') attempts to call join on undefined if res.data is null or undefined, which is common for Supabase RPC error responses. This prevents proper error handling (span status, exception capture), masks the original error, and can crash the application. A defensive check (e.g., Array.isArray(res.data)) is required. Additionally, the captureException call in instrumentRpcConsumer for Supabase errors is missing the mechanism attribute, which should be { handled: false, type: 'auto.db.supabase' }.

Fix in Cursor Fix in Web

},
},
);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Supabase Integration Errors: Exception Handling, Proxying, and Redundancy

The Supabase integration has three issues:

  1. captureException in the instrumentRpcProducer's error handling lacks a mechanism.type, violating SDK conventions for proper error classification.
  2. instrumentRpc unconditionally proxies client.rpc. If the Supabase constructor (instead of an instance) is passed to instrumentSupabaseClient, client.rpc is undefined, causing new Proxy(undefined, ...) to crash Sentry initialization.
  3. The rpc method (and schema's rpc method) is proxied without an idempotency guard. This allows multiple wraps if the integration is initialized more than once, leading to duplicate spans, breadcrumbs, and _sentry metadata injection.
Fix in Cursor Fix in Web

});
},
);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Missing Mechanism Attributes in Exception Capture

captureException calls in instrumentRpcConsumer and instrumentRpcProducer are missing required mechanism attributes. Specifically, mechanism.handled and mechanism.type are missing in instrumentRpcConsumer and the res.error path of instrumentRpcProducer. The catch path in instrumentRpcProducer sets mechanism.handled but omits mechanism.type. Per SDK guidelines, all captureException calls must include both mechanism.handled and a mechanism.type (e.g., auto.db.supabase.queue) for consistent error context and diagnostics.

Additional Locations (1)
Fix in Cursor Fix in Web

// and should not be instrumented here.
return Reflect.apply(target, thisArg, argumentsList);
}

Copy link

Choose a reason for hiding this comment

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

Bug: RPC Observability Regression

Supabase RPC calls are no longer instrumented. The PostgRESTFilterBuilder now skips /rpc paths, and the new RPC instrumentation only covers queue operations (send, send_batch, pop). This regression causes a loss of spans and breadcrumbs for all other RPC calls, impacting observability.

Fix in Cursor Fix in Web

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.

Support for Supabase Queues
4 participants