getsentry / getsentry/sentry-javascript

@sentry/astro: Cloudflare Worker server wrap not applied with @astrojs/cloudflare v14 (transform targets `astrojs-ssr-virtual-entry`, adapter now emits `virtual:cloudflare/worker-entry`)

Ouverte
#21,901 4 commentaires 0 réactions 1 personne assignée Réclamée par @JPeer264 Voir sur GitHub
Astro Cloudflare Workers Feature
Langage dominant
TypeScript
Étoiles
8.7k
Forks
1.8k
Merge moyen
1 j 17 h
PR mergées (30 j)
515

Description

## Summary

With `@astrojs/cloudflare` v14, `@sentry/astro`'s server-side init is never applied to the deployed Cloudflare Worker. The Worker's default export is left un-wrapped by `withSentry`, so server-side error/log capture does not initialize at the fetch boundary — server-side Sentry silently does nothing.

## Versions

- `@sentry/astro` 10.62.0
- `@sentry/cloudflare` 10.62.0
- `@astrojs/cloudflare` 14.0.1
- `astro` 7.0.3
- `output: 'server'`, Cloudflare **Workers** (not Pages)

## Root cause

`sentryCloudflareVitePlugin` (`packages/astro/src/integration/cloudflare.ts`) wraps the Worker by transforming the module whose id contains `astrojs-ssr-virtual-entry`:

```js
transform(code, id) {
if (!id.includes("astrojs-ssr-virtual-entry")) {
return undefined;
}
// ...rewrites `export default X;` -> `export default withSentry(() => undefined, X);`
}
```

`@astrojs/cloudflare` v14 builds the Worker through `@cloudflare/vite-plugin`, whose entry virtual module id is `virtual:cloudflare/worker-entry` (its generated body ends with `export default mod.default ?? {};`). The old `astrojs-ssr-virtual-entry` id is no longer produced, so the `transform` guard always returns early and the entry is never wrapped.

## Effect

With an app configured per the [Astro + Cloudflare docs](https://docs.sentry.io/platforms/javascript/guides/cloudflare/frameworks/astro/) (the `sentry()` integration in `astro.config` plus a `sentry.server.config.ts` doing `export default Sentry.withSentry((env) => ({ ... }), handler)`), the generated `dist/server/entry.mjs` default export is the **raw** Astro handler. Grepping all of `dist/server` for `withSentry(() =>` finds no match — the plugin's wrap never ran.

The only remaining server wiring is the injected `import "sentry.server.config.(ts|js)"` (`injectScript("page-ssr", ...)`). That runs lazily during a page render, so it doesn't deterministically instrument the Worker's fetch entry:

- errors on the first request (before any page module has evaluated the config) aren't captured;
- routes that don't pull the page-ssr module graph (e.g. API endpoints) aren't covered;
- for a Worker whose first traffic is an API route, `Sentry.init` may never run at all.

## Repro

1. Scaffold an Astro app with `output: 'server'` and the `@astrojs/cloudflare` v14 adapter (Workers, not Pages).
2. `npm i @sentry/astro @sentry/cloudflare`; add `sentry()` to `integrations`; create `sentry.server.config.ts` per the docs:
```ts
import * as Sentry from '@sentry/cloudflare'
import handler from '@astrojs/cloudflare/entrypoints/server'
export default Sentry.withSentry((env) => ({ dsn: env.SENTRY_DSN, enableLogs: true }), handler)
```
3. `astro build`.
4. Inspect `dist/server/entry.mjs`: the default export is the un-wrapped Astro handler, and `grep -r "withSentry(() =>" dist/server` returns nothing.

## Suggested fix

Have `sentryCloudflareVitePlugin`'s `transform` also match the `@cloudflare/vite-plugin` entry id `virtual:cloudflare/worker-entry` (whose default-export expression is `mod.default ?? {}`), in addition to `astrojs-ssr-virtual-entry`, so the wrap applies on `@astrojs/cloudflare` v14+.

## Workaround

For anyone hitting this before a fix lands: a tiny build-only Vite plugin that transforms the `virtual:cloudflare/worker-entry` module and wraps its `export default mod.default ?? {};` with your own `withSentry(optionsCallback, handler)` restores deterministic, eager wrapping of the Worker entry.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.