Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/happy-adults-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@spotlightjs/spotlight': minor
'@spotlightjs/electron': minor
'@spotlightjs/overlay': minor
'@spotlightjs/astro': minor
---

feat: Support versioned Sentry carrier object introduced in 8.6.0+
2 changes: 1 addition & 1 deletion demos/astro-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@astrojs/node": "^6.0.4",
"@astrojs/react": "^3.0.5",
"@astrojs/svelte": "^4.0.4",
"@sentry/astro": "^8.0.0-alpha.7",
"@sentry/astro": "8.7.0",
"@spotlightjs/astro": "workspace:*",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
Expand Down
79 changes: 51 additions & 28 deletions packages/overlay/src/integrations/sentry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,6 @@ export default function sentryIntegration(options?: SentryIntegrationOptions) {
} satisfies Integration<Envelope>;
}

type WindowWithSentry = Window & {
__SENTRY__?: {
/** Future-proof v8 way of accessing Sentry APIs via the global */
acs?: {
getCurrentScope: () => {
getClient: () => Client | undefined;
};
};
hub?: {
getClient: () => Client | undefined;
};
};
};

export function processEnvelope(rawEvent: RawEventContext) {
const { data } = rawEvent;
const [rawHeader, ...rawEntries] = data.split(/\n/gm);
Expand Down Expand Up @@ -146,6 +132,27 @@ export function processEnvelope(rawEvent: RawEventContext) {
};
}

type V8Carrier = {
stack: {
getScope?: () => {
getClient?: () => Client | undefined;
};
};
};

type LegacyCarrier = {
/** pre-v8 way of accessing client (v7 and earlier) */
hub?: {
getClient?: () => Client | undefined;
};
};

type VersionedCarrier = { version: string } & Record<Exclude<string, 'version'>, V8Carrier>;

type WindowWithSentry = Window & {
__SENTRY__?: LegacyCarrier & VersionedCarrier;
};

/**
* Takes care of injecting spotlight-specific behavior into the Sentry SDK by
* accessing the global __SENTRY__ carrier object.
Expand All @@ -167,22 +174,11 @@ function addSpotlightIntegrationToSentry(options?: SentryIntegrationOptions) {
return;
}

const sentryGlobal =
// This is what we expect the v8-stable accessor to be
(window as WindowWithSentry).__SENTRY__?.acs?.getCurrentScope() ||
// This is the current accessor (v7 and v8-alpha)
(window as WindowWithSentry).__SENTRY__?.hub;

if (!sentryGlobal) {
log(
"Couldn't find the Sentry SDK on this page. If you're using a Sentry SDK, make sure you're using version >=7.99.0 or 8.x",
);
return;
}
const sentryCarrier = (window as WindowWithSentry).__SENTRY__;
const sentryClient = sentryCarrier && getSentryClient(sentryCarrier);

const sentryClient = sentryGlobal.getClient();
if (!sentryClient) {
warn("Couldn't find a Sentry SDK client. Make sure you're using a Sentry SDK with version >=7.99.0 or 8.x");
log("Couldn't find a Sentry SDK client. Make sure you're using a Sentry SDK with version >=7.99.0 or 8.x");
return;
}

Expand Down Expand Up @@ -211,3 +207,30 @@ function addSpotlightIntegrationToSentry(options?: SentryIntegrationOptions) {

log('Added Spotlight integration to Sentry SDK');
}

/**
* Accesses the `window.__SENTRY__` carrier object and tries to get the Sentry client
* from it. This function supports all carrier object structures from v7 to all versions
* of v8.
*/
function getSentryClient(sentryCarrier: LegacyCarrier & VersionedCarrier): Client | undefined {
// 8.6.0+ way to get the client
if (sentryCarrier.version) {
const versionedCarrier = sentryCarrier[sentryCarrier.version];
const scope =
typeof versionedCarrier?.stack?.getScope === 'function' ? versionedCarrier?.stack?.getScope?.() : undefined;
if (typeof scope?.getClient === 'function') {
return scope.getClient();
}
}

// pre-8.6.0 (+v7) way to get the client
if (sentryCarrier.hub) {
const hub = sentryCarrier.hub;
if (typeof hub.getClient === 'function') {
return hub.getClient();
}
}

return undefined;
}
Loading