From cc5b51ceac3dc4a150ceb7c9276e4b1fa740172a Mon Sep 17 00:00:00 2001 From: Peter Savchenko Date: Fri, 26 Dec 2025 15:11:44 +0300 Subject: [PATCH] Log Sentry client_report items for debugging Added handling for 'client_report' items in Sentry envelopes to log their internals for easier debugging of dropped events and SDK/reporting issues. Decodes payloads as needed and logs errors if decoding fails. --- workers/sentry/src/index.ts | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/workers/sentry/src/index.ts b/workers/sentry/src/index.ts index ff71217b..9ed56c4e 100644 --- a/workers/sentry/src/index.ts +++ b/workers/sentry/src/index.ts @@ -155,6 +155,46 @@ export default class SentryEventWorker extends Worker { * Skip non-event items */ if (itemHeader.type !== 'event') { + if (itemHeader.type === 'client_report') { + /** + * Sentry "client_report" items are useful for debugging dropped events. + * We log internals here to make diagnosing SDK/reporting issues easier. + */ + try { + let decodedPayload: unknown = itemPayload; + + /** + * Sometimes Sentry parses the itemPayload as a Uint8Array. + * Decode it to JSON so it can be logged meaningfully. + */ + if (decodedPayload instanceof Uint8Array) { + const textDecoder = new TextDecoder(); + decodedPayload = textDecoder.decode(decodedPayload as Uint8Array); + } + + if (typeof decodedPayload === 'string') { + try { + decodedPayload = JSON.parse(decodedPayload); + } catch { + /** + * Keep the raw string if it isn't valid JSON. + */ + } + } + + this.logger.info('Received client_report item; logging internals:'); + this.logger.json({ + envelopeHeaders, + itemHeader, + payload: decodedPayload, + }); + } catch (clientReportError) { + this.logger.warn('Failed to decode/log client_report item:', clientReportError); + this.logger.info('👇 Here is the raw client_report item:'); + this.logger.json(item); + } + } + this.logger.info(`Skipping non-event item of type: ${itemHeader.type}`); return 'skipped'; }