From 6b82415168f4d4eb33ae955dfef5b082f5adea3d Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 30 Sep 2022 10:35:37 +0200 Subject: [PATCH 1/3] fix(node): Only set DeviceContext.boot_time if os.uptime is valid --- packages/node/src/integrations/context.ts | 12 +++++++++-- .../node/test/integrations/context.test.ts | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 packages/node/test/integrations/context.test.ts diff --git a/packages/node/src/integrations/context.ts b/packages/node/src/integrations/context.ts index 73fa8fa40c03..693c79f15bbe 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -189,10 +189,18 @@ function getAppContext(): AppContext { return { app_start_time, app_memory }; } -function getDeviceContext(deviceOpt: DeviceContextOptions | true): DeviceContext { +/** + * Gets device information from os + */ +export function getDeviceContext(deviceOpt: DeviceContextOptions | true): DeviceContext { const device: DeviceContext = {}; - device.boot_time = new Date(Date.now() - os.uptime() * 1000).toISOString(); + // os.uptime or its return value seem to be undefined in certain environments (e.g. Azure functions). + // Hence, we only set boot time, if we get a valid uptime value. + // @see https://github.com/getsentry/sentry-javascript/issues/5856 + const uptime = os.uptime && os.uptime(); + device.boot_time = uptime !== undefined ? new Date(Date.now() - uptime * 1000).toISOString() : undefined; + device.arch = os.arch(); if (deviceOpt === true || deviceOpt.memory) { diff --git a/packages/node/test/integrations/context.test.ts b/packages/node/test/integrations/context.test.ts new file mode 100644 index 000000000000..9932f0062886 --- /dev/null +++ b/packages/node/test/integrations/context.test.ts @@ -0,0 +1,21 @@ +import * as os from 'os'; +import { getDeviceContext } from '../../src/integrations/context'; + +describe('Context', () => { + describe('getDeviceContext', () => { + afterAll(() => { + jest.clearAllMocks(); + }); + + it('returns boot time if os.uptime is defined and returns a valid uptime', () => { + const deviceCtx = getDeviceContext({}); + expect(deviceCtx.boot_time).toEqual(expect.any(String)); + }); + + it('returns no boot time if os.uptime() returns undefined', () => { + jest.spyOn(os, 'uptime').mockReturnValue(undefined as unknown as number); + const deviceCtx = getDeviceContext({}); + expect(deviceCtx.boot_time).toBeUndefined(); + }); + }); +}); From 8bae3081f1de66202ac0641e5bbe00988f7a0ce1 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 30 Sep 2022 10:54:09 +0200 Subject: [PATCH 2/3] change ternary op to if stmt --- packages/node/src/integrations/context.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/node/src/integrations/context.ts b/packages/node/src/integrations/context.ts index 693c79f15bbe..c0991720d76e 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -199,7 +199,9 @@ export function getDeviceContext(deviceOpt: DeviceContextOptions | true): Device // Hence, we only set boot time, if we get a valid uptime value. // @see https://github.com/getsentry/sentry-javascript/issues/5856 const uptime = os.uptime && os.uptime(); - device.boot_time = uptime !== undefined ? new Date(Date.now() - uptime * 1000).toISOString() : undefined; + if (typeof uptime === 'number') { + device.boot_time = new Date(Date.now() - uptime * 1000).toISOString(); + } device.arch = os.arch(); From 0f6210c2581c6c8c7c445c45944df6d530928820 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 30 Sep 2022 11:04:46 +0200 Subject: [PATCH 3/3] fix linter error --- packages/node/test/integrations/context.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node/test/integrations/context.test.ts b/packages/node/test/integrations/context.test.ts index 9932f0062886..519e101187ff 100644 --- a/packages/node/test/integrations/context.test.ts +++ b/packages/node/test/integrations/context.test.ts @@ -1,4 +1,5 @@ import * as os from 'os'; + import { getDeviceContext } from '../../src/integrations/context'; describe('Context', () => {