@sentry/node-native 11.0.0-alpha.1 → 11.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  const node_worker_threads = require('node:worker_threads');
2
2
  const core = require('@sentry/core');
3
+ const server = require('@sentry/core/server');
3
4
  const node = require('@sentry/node');
4
5
  const nodeNativeStacktrace = require('@sentry/node-native-stacktrace');
5
6
  const common = require('./common.js');
@@ -78,7 +79,7 @@ function prepareStackFrames(stackFrames) {
78
79
  if (!frame.filename) {
79
80
  continue;
80
81
  }
81
- frame.in_app = core.filenameIsInApp(frame.filename);
82
+ frame.in_app = server.filenameIsInApp(frame.filename);
82
83
  if (appRootPath) {
83
84
  frame.filename = core.normalizeUrlToBase(frame.filename, appRootPath);
84
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n filenameIsInApp,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\n/**\n * Rehydrates a Scope from serialized ScopeData that has been passed over a JSON serialization boundary.\n *\n * `Scope.update()` only handles `ScopeContext` fields, so breadcrumbs have to be carried over separately.\n * Attachments are deliberately not carried over since their binary data does not survive JSON serialization.\n */\nfunction hydrateScope(data: Partial<ScopeData> | undefined): Scope {\n const scope = new Scope();\n if (data) {\n scope.update(data);\n data.breadcrumbs?.forEach(breadcrumb => scope.addBreadcrumb(breadcrumb));\n }\n return scope;\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = hydrateScope(crashedThread.pollState?.scope).getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":["workerData","POLL_RATIO","maxEventsPerHour","isRateLimited","getEnvelopeEndpointWithUrlEncodedAuth","makeNodeTransport","makeSession","updateSession","createSessionEnvelope","stripSentryFramesAndReverse","filenameIsInApp","normalizeUrlToBase","Scope","applyScopeDataToEvent","generateSpanId","captureStackTrace","uuid4","mergeScopeData","createEventEnvelope","getThreadsLastSeen"],"mappings":"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"}
1
+ {"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { filenameIsInApp } from '@sentry/core/server';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\n/**\n * Rehydrates a Scope from serialized ScopeData that has been passed over a JSON serialization boundary.\n *\n * `Scope.update()` only handles `ScopeContext` fields, so breadcrumbs have to be carried over separately.\n * Attachments are deliberately not carried over since their binary data does not survive JSON serialization.\n */\nfunction hydrateScope(data: Partial<ScopeData> | undefined): Scope {\n const scope = new Scope();\n if (data) {\n scope.update(data);\n data.breadcrumbs?.forEach(breadcrumb => scope.addBreadcrumb(breadcrumb));\n }\n return scope;\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = hydrateScope(crashedThread.pollState?.scope).getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":["workerData","POLL_RATIO","maxEventsPerHour","isRateLimited","getEnvelopeEndpointWithUrlEncodedAuth","makeNodeTransport","makeSession","updateSession","createSessionEnvelope","stripSentryFramesAndReverse","filenameIsInApp","normalizeUrlToBase","Scope","applyScopeDataToEvent","generateSpanId","captureStackTrace","uuid4","mergeScopeData","createEventEnvelope","getThreadsLastSeen"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { workerData } from 'node:worker_threads';
2
- import { getEnvelopeEndpointWithUrlEncodedAuth, uuid4, Scope, mergeScopeData, createEventEnvelope, makeSession, updateSession, createSessionEnvelope, applyScopeDataToEvent, generateSpanId, normalizeUrlToBase, stripSentryFramesAndReverse, filenameIsInApp } from '@sentry/core';
2
+ import { getEnvelopeEndpointWithUrlEncodedAuth, uuid4, Scope, mergeScopeData, createEventEnvelope, makeSession, updateSession, createSessionEnvelope, applyScopeDataToEvent, generateSpanId, normalizeUrlToBase, stripSentryFramesAndReverse } from '@sentry/core';
3
+ import { filenameIsInApp } from '@sentry/core/server';
3
4
  import { makeNodeTransport } from '@sentry/node';
4
5
  import { getThreadsLastSeen, captureStackTrace } from '@sentry/node-native-stacktrace';
5
6
  import { POLL_RATIO } from './common.js';
@@ -1 +1 @@
1
- {"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n filenameIsInApp,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\n/**\n * Rehydrates a Scope from serialized ScopeData that has been passed over a JSON serialization boundary.\n *\n * `Scope.update()` only handles `ScopeContext` fields, so breadcrumbs have to be carried over separately.\n * Attachments are deliberately not carried over since their binary data does not survive JSON serialization.\n */\nfunction hydrateScope(data: Partial<ScopeData> | undefined): Scope {\n const scope = new Scope();\n if (data) {\n scope.update(data);\n data.breadcrumbs?.forEach(breadcrumb => scope.addBreadcrumb(breadcrumb));\n }\n return scope;\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = hydrateScope(crashedThread.pollState?.scope).getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":["maxEventsPerHour","isRateLimited"],"mappings":";;;;;;AA0BA,MAAM;AAAA,EACJ,SAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA,EAAY,IAAA;AAAA,EACZ;AACF,CAAA,GAAI,UAAA;AAEJ,MAAM,eAAe,SAAA,GAAY,UAAA;AACjC,MAAM,gBAAA,uBAAuB,GAAA,EAAY;AAEzC,SAAS,OAAO,GAAA,EAAsB;AACpC,EAAA,IAAI,KAAA,EAAO;AAET,IAAA,OAAA,CAAQ,GAAA,CAAI,sCAAA,EAAwC,GAAG,GAAG,CAAA;AAAA,EAC5D;AACF;AAEA,SAAS,kBAAkBA,iBAAAA,EAAyC;AAClE,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,EAAA,OAAO,SAASC,cAAAA,GAAyB;AACvC,IAAA,MAAM,IAAA,GAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,QAAA,EAAS;AAEjC,IAAA,IAAI,SAAS,WAAA,EAAa;AACxB,MAAA,WAAA,GAAc,IAAA;AACd,MAAA,YAAA,GAAe,CAAA;AAAA,IACjB;AAEA,IAAA,IAAI,gBAAgBD,iBAAAA,EAAkB;AACpC,MAAA,IAAI,iBAAiBA,iBAAAA,EAAkB;AACrC,QAAA,YAAA,IAAgB,CAAA;AAChB,QAAA,GAAA,CAAI,CAAA,oBAAA,EAAuB,YAAY,CAAA,oBAAA,CAAsB,CAAA;AAAA,MAC/D;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,YAAA,IAAgB,CAAA;AAChB,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;AAEA,MAAM,GAAA,GAAM,qCAAA,CAAsC,GAAA,EAAK,MAAA,EAAQ,YAAY,GAAG,CAAA;AAC9E,MAAM,YAAY,iBAAA,CAAkB;AAAA,EAClC,GAAA;AAAA,EACA,oBAAoB,MAAM;AAAA,EAE1B;AACF,CAAC,CAAA;AACD,MAAM,aAAA,GAAgB,kBAAkB,gBAAgB,CAAA;AAExD,eAAe,oBAAoB,iBAAA,EAAuD;AACxF,EAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,IAAA;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,0BAA0B,CAAA;AAC9B,EAAA,MAAM,OAAA,GAAU,YAAY,iBAAiB,CAAA;AAE7C,EAAA,aAAA,CAAc,OAAA,EAAS;AAAA,IACrB,MAAA,EAAQ,UAAA;AAAA,IACR,kBAAA,EAAoB,gBAAA;AAAA,IACpB,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,qBAAA,CAAsB,OAAA,EAAS,GAAA,EAAK,aAAa,MAAM,CAAA;AAExE,EAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAE5B,EAAA,MAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAC/B;AAEA,GAAA,CAAI,SAAS,CAAA;AAEb,SAAS,mBAAmB,WAAA,EAAiE;AAC3F,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,MAAM,cAAA,GAAiB,4BAA4B,WAAW,CAAA;AAE9D,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,MAAA;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,MAAA,GAAS,eAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAG7C,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,KAAA,CAAM,QAAA,GAAW,kBAAA,CAAmB,KAAA,CAAM,QAAA,EAAU,WAAW,CAAA;AAAA,IACjE;AAAA,EACF;AAEA,EAAA,OAAO,cAAA;AACT;AAEA,SAAS,kBAAkB,QAAA,EAAkD;AAC3E,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,YAAA,EAAc,EAAE,CAAA;AAC1C;AAGA,SAAS,cAAA,CAAe,OAAc,WAAA,EAA2C;AAC/E,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,WAAW,CAAA,EAAG;AACzC,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,qBAAA,GAAwB,WAAA,GAAc,EAAC,GAAI,WAAA;AACjD,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,KAAK,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,EAAG;AACzD,MAAA,qBAAA,CAAsB,kBAAA,CAAmB,IAAA,EAAM,WAAW,CAAC,CAAA,GAAI,OAAA;AAAA,IACjE;AAAA,EACF;AAEA,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAoB;AAElD,EAAA,KAAA,MAAW,SAAA,IAAa,KAAA,CAAM,SAAA,EAAW,MAAA,IAAU,EAAC,EAAG;AACrD,IAAA,KAAA,MAAW,KAAA,IAAS,SAAA,CAAU,UAAA,EAAY,MAAA,IAAU,EAAC,EAAG;AACtD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,KAAA,CAAM,QAAA,IAAY,MAAM,QAAQ,CAAA;AACnE,MAAA,IAAI,QAAA,IAAY,qBAAA,CAAsB,QAAQ,CAAA,EAAG;AAC/C,QAAA,iBAAA,CAAkB,GAAA,CAAI,QAAA,EAAU,qBAAA,CAAsB,QAAQ,CAAC,CAAA;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,MAAA,IAAU,KAAA,CAAM,OAAA,EAAS,MAAA,IAAU,EAAC,EAAG;AAChD,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,UAAA,EAAY,MAAA,IAAU,EAAC,EAAG;AACnD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,KAAA,CAAM,QAAA,IAAY,MAAM,QAAQ,CAAA;AACnE,MAAA,IAAI,QAAA,IAAY,qBAAA,CAAsB,QAAQ,CAAA,EAAG;AAC/C,QAAA,iBAAA,CAAkB,GAAA,CAAI,QAAA,EAAU,qBAAA,CAAsB,QAAQ,CAAC,CAAA;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,SAAuB,EAAC;AAC9B,IAAA,KAAA,MAAW,CAAC,SAAA,EAAW,QAAQ,CAAA,IAAK,iBAAA,CAAkB,SAAQ,EAAG;AAC/D,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,WAAA;AAAA,QACN,SAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AACA,IAAA,KAAA,CAAM,UAAA,GAAa,EAAE,MAAA,EAAO;AAAA,EAC9B;AACF;AAEA,SAAS,sBAAA,CACP,iBACA,OAAA,EACO;AACP,EAAA,MAAM,aAAA,GAAgB,QAAQ,eAAe,CAAA;AAE7C,EAAA,OAAO;AAAA,IACL,SAAA,EAAW;AAAA,MACT,MAAA,EAAQ;AAAA,QACN;AAAA,UACE,IAAA,EAAM,kBAAA;AAAA,UACN,KAAA,EAAO,mCAAmC,SAAS,CAAA,GAAA,CAAA;AAAA,UACnD,YAAY,EAAE,MAAA,EAAQ,kBAAA,CAAmB,aAAA,EAAe,MAAM,CAAA,EAAE;AAAA;AAAA,UAEhE,SAAA,EAAW,EAAE,IAAA,EAAM,KAAA,EAAM;AAAA,UACzB,SAAA,EAAW;AAAA;AACb;AACF,KACF;AAAA,IACA,OAAA,EAAS;AAAA,MACP,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,CAAE,IAAI,CAAC,CAAC,QAAA,EAAU,WAAW,CAAA,KAAM;AAC/D,QAAA,MAAM,UAAU,QAAA,KAAa,eAAA;AAE7B,QAAA,MAAM,MAAA,GAAiB;AAAA,UACrB,EAAA,EAAI,QAAA;AAAA,UACJ,IAAA,EAAM,QAAA,KAAa,GAAA,GAAM,MAAA,GAAS,UAAU,QAAQ,CAAA,CAAA;AAAA,UACpD,OAAA;AAAA,UACA,OAAA,EAAS,IAAA;AAAA,UACT,MAAM,QAAA,KAAa;AAAA,SACrB;AAEA,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAA,CAAO,aAAa,EAAE,MAAA,EAAQ,kBAAA,CAAmB,WAAA,CAAY,MAAM,CAAA,EAAE;AAAA,QACvE;AAEA,QAAA,OAAO,MAAA;AAAA,MACT,CAAC;AAAA;AACH,GACF;AACF;AAQA,SAAS,aAAa,IAAA,EAA6C;AACjE,EAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AACjB,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,CAAA,UAAA,KAAc,KAAA,CAAM,aAAA,CAAc,UAAU,CAAC,CAAA;AAAA,EACzE;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,iBAAA,CAAkB,OAAc,KAAA,EAAwB;AAC/D,EAAA,qBAAA,CAAsB,OAAO,KAAK,CAAA;AAElC,EAAA,IAAI,CAAC,KAAA,CAAM,QAAA,EAAU,KAAA,EAAO;AAC1B,IAAA,MAAM,EAAE,OAAA,EAAS,YAAA,EAAc,iBAAA,KAAsB,KAAA,CAAM,kBAAA;AAC3D,IAAA,KAAA,CAAM,QAAA,GAAW;AAAA,MACf,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,OAAA;AAAA,QACV,OAAA,EAAS,qBAAqB,cAAA,EAAe;AAAA,QAC7C,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,GAAG,KAAA,CAAM;AAAA,KACX;AAAA,EACF;AACF;AAEA,eAAe,eAAe,eAAA,EAAwC;AACpE,EAAA,IAAI,eAAc,EAAG;AACnB,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,iBAAA,EAA8C;AAC9D,EAAA,MAAM,aAAA,GAAgB,QAAQ,eAAe,CAAA;AAE7C,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,GAAA,CAAI,CAAA,yBAAA,EAA4B,eAAe,CAAA,CAAA,CAAG,CAAA;AAClD,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,mBAAA,CAAoB,aAAA,CAAc,SAAA,EAAW,OAAO,CAAA;AAAA,EAC5D,SAAS,KAAA,EAAO;AACd,IAAA,GAAA,CAAI,CAAA,4CAAA,EAA+C,eAAe,CAAA,EAAA,CAAA,EAAM,KAAK,CAAA;AAAA,EAC/E;AAEA,EAAA,GAAA,CAAI,eAAe,CAAA;AAEnB,EAAA,MAAM,KAAA,GAAe;AAAA,IACnB,UAAU,KAAA,EAAM;AAAA,IAChB,QAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA,EAAU,MAAA;AAAA,IACV,KAAA,EAAO,OAAA;AAAA,IACP,IAAA;AAAA,IACA,GAAG,sBAAA,CAAuB,eAAA,EAAiB,OAAO;AAAA,GACpD;AAEA,EAAA,MAAM,QAAQ,YAAA,CAAa,aAAA,CAAc,SAAA,EAAW,KAAK,EAAE,YAAA,EAAa;AAExE,EAAA,IAAI,aAAA,EAAe,YAAY,cAAA,EAAgB;AAE7C,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,IAAS,aAAA,CAAc,UAAA,CAAW,cAAc,CAAA,CAAE,YAAA,EAAa;AACxG,IAAA,cAAA,CAAe,OAAO,cAAc,CAAA;AAAA,EACtC;AACA,EAAA,iBAAA,CAAkB,OAAO,KAAK,CAAA;AAE9B,EAAA,MAAM,cAAA,GAAyC,OAAO,MAAA,CAAO,OAAO,EAAE,MAAA,CAAO,CAAC,KAAK,WAAA,KAAgB;AACjG,IAAA,OAAO,EAAE,GAAG,GAAA,EAAK,GAAG,WAAA,CAAY,WAAW,WAAA,EAAY;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,cAAA,CAAe,OAAO,cAAc,CAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,mBAAA,CAAoB,KAAA,EAAO,GAAA,EAAK,aAAa,MAAM,CAAA;AAEpE,EAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAE5B,EAAA,MAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAC7B,EAAA,MAAM,SAAA,CAAU,MAAM,GAAI,CAAA;AAC5B;AAEA,WAAA,CAAY,YAAY;AACtB,EAAA,KAAA,MAAW,CAAC,UAAU,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,kBAAA,EAAoB,CAAA,EAAG;AACnE,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,QAAQ,CAAA,EAAG;AAClC,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,CAAA,yBAAA,EAA4B,QAAQ,CAAA,cAAA,EAAiB,IAAI,CAAA,QAAA,CAAU,CAAA;AACvE,MAAA,gBAAA,CAAiB,IAAI,QAAQ,CAAA;AAE7B,MAAA,IAAI;AACF,QAAA,MAAM,eAAe,QAAQ,CAAA;AAAA,MAC/B,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,CAAA,iCAAA,EAAoC,QAAQ,CAAA,EAAA,CAAA,EAAM,KAAK,CAAA;AAAA,MAC7D;AAAA,IACF,CAAA,MAAO;AACL,MAAA,gBAAA,CAAiB,OAAO,QAAQ,CAAA;AAAA,IAClC;AAAA,EACF;AACF,CAAA,EAAG,YAAY,CAAA"}
1
+ {"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { filenameIsInApp } from '@sentry/core/server';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\n/**\n * Rehydrates a Scope from serialized ScopeData that has been passed over a JSON serialization boundary.\n *\n * `Scope.update()` only handles `ScopeContext` fields, so breadcrumbs have to be carried over separately.\n * Attachments are deliberately not carried over since their binary data does not survive JSON serialization.\n */\nfunction hydrateScope(data: Partial<ScopeData> | undefined): Scope {\n const scope = new Scope();\n if (data) {\n scope.update(data);\n data.breadcrumbs?.forEach(breadcrumb => scope.addBreadcrumb(breadcrumb));\n }\n return scope;\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = hydrateScope(crashedThread.pollState?.scope).getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":["maxEventsPerHour","isRateLimited"],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"11.0.0-alpha.1","sideEffects":false}
1
+ {"type":"module","version":"11.0.0-beta.0","sideEffects":false}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/node-native",
3
- "version": "11.0.0-alpha.1",
3
+ "version": "11.0.0-beta.0",
4
4
  "description": "Native Tools for the Official Sentry Node.js SDK",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-native",
@@ -43,6 +43,7 @@
43
43
  "scripts": {
44
44
  "clean": "rm -rf build",
45
45
  "lint": "oxlint . --type-aware",
46
+ "lint:types": "oxlint src --type-aware --type-check",
46
47
  "lint:es-compatibility": "es-check es2022 ./build/cjs/*.js && es-check es2022 ./build/esm/*.js --module",
47
48
  "lint:fix": "oxlint . --fix --type-aware",
48
49
  "build": "yarn build:types && yarn build:transpile",
@@ -55,8 +56,8 @@
55
56
  },
56
57
  "dependencies": {
57
58
  "@sentry/node-native-stacktrace": "^0.5.1",
58
- "@sentry/core": "11.0.0-alpha.1",
59
- "@sentry/node": "11.0.0-alpha.1"
59
+ "@sentry/core": "11.0.0-beta.0",
60
+ "@sentry/node": "11.0.0-beta.0"
60
61
  },
61
62
  "devDependencies": {
62
63
  "@types/node": "^18.19.1"