Skip to content

Commit

Permalink
fix: Don't crash on bigints (#1573)
Browse files Browse the repository at this point in the history
  • Loading branch information
robbie-c authored Nov 30, 2024
1 parent a151df5 commit fce2141
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/__tests__/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,21 @@ describe('request', () => {
'application/x-www-form-urlencoded'
)
})
it('converts bigint properties to string without throwing', () => {
request(
createRequest({
url: 'https://any.posthog-instance.com/',
method: 'POST',
compression: Compression.Base64,
data: { foo: BigInt('999999999999999999999') },
})
)
expect(mockedXHR.send.mock.calls[0][0]).toMatchInlineSnapshot(
`"data=eyJmb28iOiI5OTk5OTk5OTk5OTk5OTk5OTk5OTkifQ%3D%3D"`
)
expect(mockedXHR.setRequestHeader).toHaveBeenCalledWith('Content-Type', 'application/x-www-form-urlencoded')
})
})
describe('sendBeacon', () => {
Expand Down
17 changes: 13 additions & 4 deletions src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,17 @@ export const extendURLParams = (url: string, params: Record<string, any>): strin
return `${baseUrl}?${newSearch}`
}

export const jsonStringify = (data: any, space?: string | number): string => {
// With plain JSON.stringify, we get an exception when a property is a BigInt. This has caused problems for some users,
// see https://github.com/PostHog/posthog-js/issues/1440
// To work around this, we convert BigInts to strings before stringifying the data. This is not ideal, as we lose
// information that this was originally a number, but given ClickHouse doesn't support BigInts, the customer
// would not be able to operate on these numerically anyway.
return JSON.stringify(data, (_, value) => (typeof value === 'bigint' ? value.toString() : value), space)
}

const encodeToDataString = (data: string | Record<string, any>): string => {
return 'data=' + encodeURIComponent(typeof data === 'string' ? data : JSON.stringify(data))
return 'data=' + encodeURIComponent(typeof data === 'string' ? data : jsonStringify(data))
}

const encodePostData = ({ data, compression }: RequestOptions): EncodedBody | undefined => {
Expand All @@ -51,7 +60,7 @@ const encodePostData = ({ data, compression }: RequestOptions): EncodedBody | un
}

if (compression === Compression.GZipJS) {
const gzipData = gzipSync(strToU8(JSON.stringify(data)), { mtime: 0 })
const gzipData = gzipSync(strToU8(jsonStringify(data)), { mtime: 0 })
const blob = new Blob([gzipData], { type: CONTENT_TYPE_PLAIN })
return {
contentType: CONTENT_TYPE_PLAIN,
Expand All @@ -61,7 +70,7 @@ const encodePostData = ({ data, compression }: RequestOptions): EncodedBody | un
}

if (compression === Compression.Base64) {
const b64data = _base64Encode(JSON.stringify(data))
const b64data = _base64Encode(jsonStringify(data))
const encodedBody = encodeToDataString(b64data)

return {
Expand All @@ -71,7 +80,7 @@ const encodePostData = ({ data, compression }: RequestOptions): EncodedBody | un
}
}

const jsonBody = JSON.stringify(data)
const jsonBody = jsonStringify(data)
return {
contentType: CONTENT_TYPE_JSON,
body: jsonBody,
Expand Down

0 comments on commit fce2141

Please sign in to comment.