Skip to content

feat(effect): Support v4 beta#20394

Open
JPeer264 wants to merge 2 commits intojp/effect-v4from
jp/effect-v4-core
Open

feat(effect): Support v4 beta#20394
JPeer264 wants to merge 2 commits intojp/effect-v4from
jp/effect-v4-core

Conversation

@JPeer264
Copy link
Copy Markdown
Member

This adds support to Effect v4, but also keeps the compatibility for v3. There is no way that we can unit test against v3, as the devDependencies need to use effect@4 and an updated @effect/vitest version, which is not compatible with Effect v3 (this is added in #20389).

The API for Effect v4 has changed a little, so there are safeguards to detect if it is v3 or v4 and uses the correct API. The good part is that for users nothing changed, so they still can use the same methods in their app as before (ofc, respecting the new Effect v4 API).

Before (Effect v3):

const SentryLive = Layer.mergeAll(
  Sentry.effectLayer({
    dsn: '__DSN__',
    tracesSampleRate: 1.0,
    enableLogs: true,
  }),
  Layer.setTracer(Sentry.SentryEffectTracer),
  Logger.replace(Logger.defaultLogger, Sentry.SentryEffectLogger),
  Sentry.SentryEffectMetricsLayer,
);

After (Effect v4):

const SentryLive = Layer.mergeAll(
  Sentry.effectLayer({
    dsn: '__DSN__',
    tracesSampleRate: 1.0,
    enableLogs: true,
  }),
  Layer.succeed(Tracer.Tracer, Sentry.SentryEffectTracer),
  Logger.layer([Sentry.SentryEffectLogger]),
  Sentry.SentryEffectMetricsLayer,
);

Both usages still work and are represented in the E2E tests.

@JPeer264 JPeer264 self-assigned this Apr 20, 2026

// Use bracket notation to avoid Webpack static analysis flagging missing exports
// This is important for Effect v3 compatibility.
const MetricModule = Metric;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a little hack I had to do in order to support Effect v3 in the browser. It seems that Webpack checks if snapshotUnsafe is available and fails if it doesn't. snapshotUnsafe is for Effect v4 and is not part of the package. By using MetricModule it is possible to work around this issue.

@JPeer264 JPeer264 force-pushed the jp/effect-v4-core branch from 0ddfb1b to 0f6b4de Compare April 20, 2026 07:00
@JPeer264 JPeer264 marked this pull request as ready for review April 20, 2026 07:09
@JPeer264 JPeer264 requested review from andreiborza and s1gr1d April 20, 2026 07:09
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 20, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.78 kB added added
@sentry/browser - with treeshaking flags 24.27 kB added added
@sentry/browser (incl. Tracing) 43.65 kB added added
@sentry/browser (incl. Tracing + Span Streaming) 45.36 kB added added
@sentry/browser (incl. Tracing, Profiling) 48.58 kB added added
@sentry/browser (incl. Tracing, Replay) 82.79 kB added added
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 72.29 kB added added
@sentry/browser (incl. Tracing, Replay with Canvas) 87.49 kB added added
@sentry/browser (incl. Tracing, Replay, Feedback) 99.74 kB added added
@sentry/browser (incl. Feedback) 42.59 kB added added
@sentry/browser (incl. sendFeedback) 30.45 kB added added
@sentry/browser (incl. FeedbackAsync) 35.45 kB added added
@sentry/browser (incl. Metrics) 27.07 kB added added
@sentry/browser (incl. Logs) 27.2 kB added added
@sentry/browser (incl. Metrics & Logs) 27.89 kB added added
@sentry/react 27.53 kB added added
@sentry/react (incl. Tracing) 45.92 kB added added
@sentry/vue 30.61 kB added added
@sentry/vue (incl. Tracing) 45.49 kB added added
@sentry/svelte 25.8 kB added added
CDN Bundle 28.46 kB added added
CDN Bundle (incl. Tracing) 44.73 kB added added
CDN Bundle (incl. Logs, Metrics) 29.83 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) 45.81 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) 68.73 kB added added
CDN Bundle (incl. Tracing, Replay) 81.68 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 82.77 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) 87.2 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 88.27 kB added added
CDN Bundle - uncompressed 83.12 kB added added
CDN Bundle (incl. Tracing) - uncompressed 133.75 kB added added
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.27 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 137.17 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 210.63 kB added added
CDN Bundle (incl. Tracing, Replay) - uncompressed 250.99 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 254.38 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 263.9 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 267.29 kB added added
@sentry/nextjs (client) 48.44 kB added added
@sentry/sveltekit (client) 44.09 kB added added
@sentry/node-core 57.94 kB added added
@sentry/node 174.78 kB added added
@sentry/node - without tracing 97.89 kB added added
@sentry/aws-serverless 115.12 kB added added

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0f6b4de. Configure here.

Comment thread packages/effect/src/metrics.ts
Copy link
Copy Markdown
Member

@s1gr1d s1gr1d left a comment

Choose a reason for hiding this comment

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

Looks good 👍

Just a general comment: when trying to differentiate the logic between v3 and v4 you always check for the structure of specific objects. If e.g. in v4 cause.reasons is always an array of Reason objects, you could theoretically just do something like isV4() and then apply the logic. But I am not sure if there is an easy way of finding out the used version (maybe checking the package.json)

@JPeer264
Copy link
Copy Markdown
Member Author

If e.g. in v4 cause.reasons is always an array of Reason objects, you could theoretically just do something like isV4() and then apply the logic. But I am not sure if there is an easy way of finding out the used version (maybe checking the package.json)

I thought for it to make it more generic, but since we do not have any bundler plugin or similar there is no chance to check for it. Effect itself doesn't have a versioning internally, which makes it harder.

Comment on lines +39 to +43
const V3_COUNTER_STATE_TYPE_ID = Symbol.for('effect/MetricState/Counter');
const V3_GAUGE_STATE_TYPE_ID = Symbol.for('effect/MetricState/Gauge');
const V3_HISTOGRAM_STATE_TYPE_ID = Symbol.for('effect/MetricState/Histogram');
const V3_SUMMARY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Summary');
const V3_FREQUENCY_STATE_TYPE_ID = Symbol.for('effect/MetricState/Frequency');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The hardcoded symbols used for Effect v3 metric detection are untested. If they are incorrect, v3 metrics will be silently dropped.
Severity: HIGH

Suggested Fix

Add an E2E test case for the effect-node (v3) application that specifically sends and verifies metrics. This will validate that the hardcoded symbol keys are correct and that metrics are being reported as expected for Effect v3 users.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/effect/src/metrics.ts#L39-L43

Potential issue: The code uses hardcoded, globally-registered symbols (e.g.,
`Symbol.for('effect/MetricState/Counter')`) to detect Effect v3 metric types. This logic
is not covered by any unit or E2E tests, as the test suite only runs against Effect v4.
If these symbol keys do not exactly match the internal symbols used by Effect v3, the
`sendV3MetricToSentry` function will fail to identify any metrics, causing them to be
silently dropped without any errors or warnings.

Also affects:

  • packages/effect/src/metrics.ts:71~94

Did we get this right? 👍 / 👎 to inform future reviews.

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