Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 6 additions & 4 deletions packages/utils/src/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ function getWalkSource(
[key: string]: any;
} = {};

// Accessing event attributes can throw (see https://github.com/getsentry/sentry-javascript/issues/768 and
// https://github.com/getsentry/sentry-javascript/issues/838), but accessing `type` hasn't been wrapped in a
// try-catch in at least two years and no one's complained, so that's likely not an issue anymore
source.type = event.type;

// Accessing event.target can throw (see getsentry/raven-js#838, #768)
try {
source.target = isElement(event.target)
? htmlTreeAsString(event.target)
Expand All @@ -131,9 +133,9 @@ function getWalkSource(
source.detail = event.detail;
}

for (const i in event) {
if (Object.prototype.hasOwnProperty.call(event, i)) {
source[i] = event;
for (const attr in event) {
if (Object.prototype.hasOwnProperty.call(event, attr)) {
source[attr] = event[attr];
}
}

Expand Down
74 changes: 53 additions & 21 deletions packages/utils/test/object.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
/**
* @jest-environment jsdom
*/

import * as isModule from '../src/is';
import { dropUndefinedKeys, extractExceptionKeysForMessage, fill, normalize, urlEncode } from '../src/object';
import { testOnlyIfNodeVersionAtLeast } from './testutils';

describe('fill()', () => {
test('wraps a method by calling a replacement function on it', () => {
Expand Down Expand Up @@ -119,28 +125,54 @@ describe('normalize()', () => {
});
});

test('extracts extra properties from error objects', () => {
const obj = new Error('Wubba Lubba Dub Dub') as any;
obj.reason = new TypeError("I'm pickle Riiick!");
obj.extra = 'some extra prop';

obj.stack = 'x';
obj.reason.stack = 'x';

// IE 10/11
delete obj.description;
delete obj.reason.description;

expect(normalize(obj)).toEqual({
message: 'Wubba Lubba Dub Dub',
name: 'Error',
stack: 'x',
reason: {
message: "I'm pickle Riiick!",
name: 'TypeError',
describe('getWalkSource()', () => {
test('extracts extra properties from error objects', () => {
const obj = new Error('Wubba Lubba Dub Dub') as any;
obj.reason = new TypeError("I'm pickle Riiick!");
obj.extra = 'some extra prop';

obj.stack = 'x';
obj.reason.stack = 'x';

// IE 10/11
delete obj.description;
delete obj.reason.description;

expect(normalize(obj)).toEqual({
message: 'Wubba Lubba Dub Dub',
name: 'Error',
stack: 'x',
},
extra: 'some extra prop',
reason: {
message: "I'm pickle Riiick!",
name: 'TypeError',
stack: 'x',
},
extra: 'some extra prop',
});
});

testOnlyIfNodeVersionAtLeast(8)('extracts data from `Event` objects', () => {
const isElement = jest.spyOn(isModule, 'isElement').mockReturnValue(true);
const getAttribute = () => undefined;

const parkElement = { tagName: 'PARK', getAttribute };
const treeElement = { tagName: 'TREE', parentNode: parkElement, getAttribute };
const squirrelElement = { tagName: 'SQUIRREL', parentNode: treeElement, getAttribute };

const chaseEvent = new Event('chase');
Object.defineProperty(chaseEvent, 'target', { value: squirrelElement });
Object.defineProperty(chaseEvent, 'currentTarget', { value: parkElement });
Object.defineProperty(chaseEvent, 'wagging', { value: true, enumerable: false });

expect(normalize(chaseEvent)).toEqual({
currentTarget: 'park',
isTrusted: false,
target: 'park > tree > squirrel',
type: 'chase',
// notice that `wagging` isn't included because it's not enumerable and not one of the ones we specifically extract
});

isElement.mockRestore();
});
});

Expand Down
13 changes: 13 additions & 0 deletions packages/utils/test/testutils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => {
const currentNodeVersion = process.env.NODE_VERSION;

try {
if (Number(currentNodeVersion?.split('.')[0]) < minVersion) {
return it.skip;
}
} catch (oO) {
// we can't tell, so err on the side of running the test
}

return it;
};