Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions .changeset/warm-foxes-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'posthog-node': patch
---

fix: captureException now uses distinctId from request context
38 changes: 38 additions & 0 deletions packages/node/src/__tests__/context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,42 @@ describe('PostHog Context', () => {
expect(body.distinct_id).toBe('explicit-user')
})
})

it.each([
{
label: 'no distinctId and no context → personless',
contextDistinctId: undefined,
explicitDistinctId: undefined,
expectedDistinctId: (id: string) => expect(typeof id).toBe('string'),
expectedProcessPersonProfile: false,
},
{
label: 'context distinctId only → uses context',
contextDistinctId: 'context-user',
explicitDistinctId: undefined,
expectedDistinctId: (id: string) => expect(id).toBe('context-user'),
expectedProcessPersonProfile: undefined,
},
{
label: 'explicit distinctId overrides context',
contextDistinctId: 'context-user',
explicitDistinctId: 'explicit-user',
expectedDistinctId: (id: string) => expect(id).toBe('explicit-user'),
expectedProcessPersonProfile: undefined,
},
])(
'captureException $label',
async ({ contextDistinctId, explicitDistinctId, expectedDistinctId, expectedProcessPersonProfile }) => {
const run = () => posthog.captureException(new Error('test error'), explicitDistinctId)
contextDistinctId ? posthog.withContext({ distinctId: contextDistinctId }, run) : run()

await waitForFlush()

const events = getLastBatchEvents()
expect(events).toHaveLength(1)
expect(events?.[0].event).toBe('$exception')
expectedDistinctId(events?.[0].distinct_id)
expect(events?.[0].properties.$process_person_profile).toBe(expectedProcessPersonProfile)
}
)
})
12 changes: 4 additions & 8 deletions packages/node/src/extensions/error-tracking/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { addUncaughtExceptionListener, addUnhandledRejectionListener } from './autocapture'
import { PostHogBackendClient } from '@/client'
import { isObject, uuidv7 } from '@posthog/core'
import { isObject } from '@posthog/core'
import { EventMessage, PostHogOptions } from '@/types'
import type { Logger } from '@posthog/core'
import { BucketedRateLimiter } from '@posthog/core'
Expand Down Expand Up @@ -46,20 +46,16 @@ export default class ErrorTracking {
): Promise<EventMessage> {
const properties: EventMessage['properties'] = { ...additionalProperties }

// Given stateless nature of Node SDK we capture exceptions using personless processing when no
// user can be determined because a distinct_id is not provided e.g. exception autocapture
if (!distinctId) {
properties.$process_person_profile = false
}

const exceptionProperties = this.errorPropertiesBuilder.buildFromUnknown(error, hint)
exceptionProperties.$exception_list = await this.errorPropertiesBuilder.modifyFrames(
exceptionProperties.$exception_list
)

return {
event: '$exception',
distinctId: distinctId || uuidv7(),
// Leave distinctId resolution to prepareEventMessage which checks request context
// and falls back to a random UUID with $process_person_profile = false
distinctId: distinctId,
properties: {
...exceptionProperties,
...properties,
Expand Down
Loading