Report updater errors through @sentry/core

The updaters run in the container today and in a Worker next, and
@sentry/node cannot be bundled into a Worker. Both @sentry/node and
@sentry/cloudflare are built on @sentry/core, where captureException
lives, so the updater base class imports from core and lands on whichever
client the entry point initialized. The Node entry point keeps
initializing @sentry/node; the Worker will use @sentry/cloudflare.

The two packages must stay on the same version: Sentry keys its global
carrier by version, and a split silently drops events. A test pins the
routing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Matt Isenhower
2026-09-05 10:23:35 -07:00
parent 67ce13ef9f
commit 41dcff1709
4 changed files with 69 additions and 47 deletions

91
package-lock.json generated
View File

@@ -8,7 +8,8 @@
"dependencies": {
"@atproto/api": "^0.20.42",
"@aws-sdk/client-s3": "^3.1121.0",
"@sentry/node": "^10.72.0",
"@sentry/core": "^10.73.0",
"@sentry/node": "^10.73.0",
"bulma": "^0.9.4",
"bulma-tooltip": "^3.0.2",
"console-stamp": "^3.1.2",
@@ -3961,9 +3962,9 @@
}
},
"node_modules/@opentelemetry/core": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz",
"integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.11.0.tgz",
"integrity": "sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/semantic-conventions": "^1.29.0"
@@ -3993,12 +3994,12 @@
}
},
"node_modules/@opentelemetry/resources": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz",
"integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.11.0.tgz",
"integrity": "sha512-Ie7+8q8MDF4FAEQCKVMTx3ReUvxiIAgIiiW3c9JdmP8+HMcDy20puT+AHjexnExgnbvBxjQ9fjkFDWrikJ2jQA==",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/core": "2.10.0",
"@opentelemetry/core": "2.11.0",
"@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
@@ -4009,13 +4010,13 @@
}
},
"node_modules/@opentelemetry/sdk-trace": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz",
"integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.11.0.tgz",
"integrity": "sha512-fFnTqGm8/G73GQVnxYi7LXa1ZVYEUvgL6XI1LpvV0bPC7WQ/ZGgKxCSl8FnlZBKto9JHHEFTO6s6CUpvvtwFrA==",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/core": "2.10.0",
"@opentelemetry/resources": "2.10.0",
"@opentelemetry/core": "2.11.0",
"@opentelemetry/resources": "2.11.0",
"@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
@@ -4026,14 +4027,14 @@
}
},
"node_modules/@opentelemetry/sdk-trace-base": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz",
"integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.11.0.tgz",
"integrity": "sha512-H19x/TX/LZdqiYOjM7fqtSxwlplC5pgelavqbQdHbhdq0q/AI/TGkM2dfGuuynTXmJPeF2HoZVoPDu+TGoW78A==",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/core": "2.10.0",
"@opentelemetry/resources": "2.10.0",
"@opentelemetry/sdk-trace": "2.10.0",
"@opentelemetry/core": "2.11.0",
"@opentelemetry/resources": "2.11.0",
"@opentelemetry/sdk-trace": "2.11.0",
"@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
@@ -4865,9 +4866,9 @@
}
},
"node_modules/@sentry/core": {
"version": "10.72.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.72.0.tgz",
"integrity": "sha512-UJMHZfbjP4qk+g4AQhZmzosMdICC2D9p0/hLrm1LofPsp+WBfcSnv9jsY1a9TfmpS4WCAmTx8nANYTIXifcBjA==",
"version": "10.73.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.73.0.tgz",
"integrity": "sha512-FLO1UgH19RyasVpofu612WCOgb2nEH0dZy+R72d7p65XU9i0wxlMKm3+sgfwKmiSJp1Qhilaaxs4Jg6BbiM5HA==",
"license": "MIT",
"dependencies": {
"@sentry/conventions": "^0.16.0"
@@ -4877,19 +4878,19 @@
}
},
"node_modules/@sentry/node": {
"version": "10.72.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.72.0.tgz",
"integrity": "sha512-eQHQFxSX26MhG/nB+tAY4QRslnPvJse7pww/hd3zXAqNULRa5lFtjSLALcHx/KUVDCZdTPdUVZEj4nGidcHrow==",
"version": "10.73.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.73.0.tgz",
"integrity": "sha512-jiMJ6GgXDw6UMGzJY+o0c8OoeA9OfHqZ/xEpHfDqy75hn+9CEkRkbNGCIdMvsc7wW/Se1Os394hHfTpU+YEskg==",
"license": "MIT",
"dependencies": {
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/instrumentation": "^0.220.0",
"@opentelemetry/sdk-trace-base": "^2.9.0",
"@sentry/conventions": "^0.16.0",
"@sentry/core": "10.72.0",
"@sentry/node-core": "10.72.0",
"@sentry/opentelemetry": "10.72.0",
"@sentry/server-utils": "10.72.0",
"@sentry/core": "10.73.0",
"@sentry/node-core": "10.73.0",
"@sentry/opentelemetry": "10.73.0",
"@sentry/server-utils": "10.73.0",
"import-in-the-middle": "^3.0.0"
},
"engines": {
@@ -4897,14 +4898,14 @@
}
},
"node_modules/@sentry/node-core": {
"version": "10.72.0",
"resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.72.0.tgz",
"integrity": "sha512-xYuYWmWEWnN8h3YHa7mds212ANFgrxfrbmLvVg0p0wf9m6MFjLowOTmjaiK0XW20sM/veSelicre650bx8UFtQ==",
"version": "10.73.0",
"resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.73.0.tgz",
"integrity": "sha512-GHAGUmZPmm6FKfxfv2maVVJ/A99YAmd7oFOuKMDmITI6O/Msl6JB3vPTEpopVAHLW0LYJQBOjddL9C7o+Jt44g==",
"license": "MIT",
"dependencies": {
"@sentry/conventions": "^0.16.0",
"@sentry/core": "10.72.0",
"@sentry/opentelemetry": "10.72.0",
"@sentry/core": "10.73.0",
"@sentry/opentelemetry": "10.73.0",
"import-in-the-middle": "^3.0.0"
},
"engines": {
@@ -4936,13 +4937,13 @@
}
},
"node_modules/@sentry/opentelemetry": {
"version": "10.72.0",
"resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.72.0.tgz",
"integrity": "sha512-ZVbAM1rGU/awN7cH/jvC87WpQw0NOJx5id6dKnnefStXpP/kUnZXYhtX9gfBnofYvJWa5I5VUSeuKCLUcKL75w==",
"version": "10.73.0",
"resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.73.0.tgz",
"integrity": "sha512-fQouPQKsH0CQrw6oAn1k0Z2I+tgyochCovifr5qNS69i0OzjknLa03WJyiZ/IuzXc4AVa5jAKfOeE9slABz8Qw==",
"license": "MIT",
"dependencies": {
"@sentry/conventions": "^0.16.0",
"@sentry/core": "10.72.0"
"@sentry/core": "10.73.0"
},
"engines": {
"node": ">=18"
@@ -4954,13 +4955,13 @@
}
},
"node_modules/@sentry/server-utils": {
"version": "10.72.0",
"resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.72.0.tgz",
"integrity": "sha512-CWpHMYW81RDBSVBdnxulGUvvBhkBb/OpSr72ubSe1UkKTcgT0NDMCWxE3dLFXqSxzT4DaF5UlUVv9ii5Sse53w==",
"version": "10.73.0",
"resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.73.0.tgz",
"integrity": "sha512-QskripdKFbM/+gipC6mpa2crLwL7+VbkX84IpHg2z9UlYQ1kNKd3aMT+Qk9NLRSw/zu1rSIAvlbWfx4D3rgNAA==",
"license": "MIT",
"dependencies": {
"@sentry/conventions": "^0.16.0",
"@sentry/core": "10.72.0"
"@sentry/core": "10.73.0"
},
"engines": {
"node": ">=18"
@@ -10225,9 +10226,9 @@
}
},
"node_modules/import-in-the-middle": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.3.3.tgz",
"integrity": "sha512-AiohS3H80sXO6owEltjGX+glb7qXaDhBoJb9XcQVH4UI207xu/bDLUcadVKp7Qe576reg9yr/PXZjV5qx8gfbA==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.4.0.tgz",
"integrity": "sha512-Xfjwfarhe+LGmoaof+sexeNo3sGRysb5x56WrZLwHtmqT0OilSKtVWkv0lrCcMgSKyKP9oBogBAisHZvtJH0aw==",
"license": "Apache-2.0",
"dependencies": {
"cjs-module-lexer": "^2.2.0",

View File

@@ -29,7 +29,8 @@
"dependencies": {
"@atproto/api": "^0.20.42",
"@aws-sdk/client-s3": "^3.1121.0",
"@sentry/node": "^10.72.0",
"@sentry/core": "^10.73.0",
"@sentry/node": "^10.73.0",
"bulma": "^0.9.4",
"bulma-tooltip": "^3.0.2",
"console-stamp": "^3.1.2",

View File

@@ -2,7 +2,7 @@ import _ from 'lodash';
import jsonpath from '../../../common/jsonpath.js';
import SplatNet from '../../../common/splatnet.js';
import { createEvents } from 'ics';
import * as Sentry from '@sentry/node';
import * as Sentry from '@sentry/core'; // not @sentry/node: this file also runs in a Worker (see test/sentry.test.js)
import { languages } from '../../../common/regions.js';
import LocalizationProcessor from '../LocalizationProcessor.js';
import { DATA_CACHE_CONTROL } from '../../../common/storage/index.js';

20
test/sentry.test.js Normal file
View File

@@ -0,0 +1,20 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import * as SentryNode from '@sentry/node';
import { captureException } from '@sentry/core';
// Shared code (the updaters) reports through @sentry/core so it runs unchanged under
// @sentry/node and @sentry/cloudflare. That only works while both resolve to one copy of
// core: Sentry keys its global carrier by version, so a version split silently drops events.
test('captureException from @sentry/core reaches the client @sentry/node initialized', async () => {
const seen = [];
SentryNode.init({
dsn: 'https://public@example.ingest.sentry.io/1',
beforeSend: event => { seen.push(event.exception.values[0].value); return null; },
});
captureException(new Error('routed through core'));
await SentryNode.flush(1000);
assert.deepEqual(seen, ['routed through core']);
});