Skip to content

Commit

Permalink
fix(core): Always instantiate global Error class in injected code s…
Browse files Browse the repository at this point in the history
…nippets (#594)

Ensures that we always use the `Error` class explicitly from the global object instead of the "ambient" `Error` class. The reason is that users (or as reported frameworks) are free to name their own classes "Error" in which case the file injection would instantiate the user-created and not the global class.
  • Loading branch information
Lms24 committed Aug 27, 2024
1 parent 6993888 commit 22b9a47
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ try {
? self
: {};

var stack = new Error().stack;
var stack = new globalObject.Error().stack;

if (stack) {
globalObject._sentryDebugIds = globalObject._sentryDebugIds || {};
Expand Down
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ export function createComponentNameAnnotateHooks() {
}

export function getDebugIdSnippet(debugId: string): string {
return `;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}}();`;
return `;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}}();`;
}

export { stringToUUID, replaceBooleanFlagsInCode } from "./utils";
Expand Down
4 changes: 2 additions & 2 deletions packages/bundler-plugin-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,10 @@ export function generateModuleMetadataInjectorCode(metadata: any) {
_sentryModuleMetadataGlobal._sentryModuleMetadata =
_sentryModuleMetadataGlobal._sentryModuleMetadata || {};
_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack] =
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack] =
Object.assign(
{},
_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack],
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack],
${JSON.stringify(metadata)}
);
}`;
Expand Down
10 changes: 10 additions & 0 deletions packages/bundler-plugin-core/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getDebugIdSnippet } from "../src";

describe("getDebugIdSnippet", () => {
it("returns the debugId injection snippet for a passed debugId", () => {
const snippet = getDebugIdSnippet("1234");
expect(snippet).toMatchInlineSnapshot(
`";!function(){try{var e=\\"undefined\\"!=typeof window?window:\\"undefined\\"!=typeof global?global:\\"undefined\\"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\\"1234\\",e._sentryDebugIdIdentifier=\\"sentry-dbid-1234\\")}catch(e){}}();"`
);
});
});
62 changes: 62 additions & 0 deletions packages/bundler-plugin-core/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
generateModuleMetadataInjectorCode,
getDependencies,
getPackageJson,
parseMajorVersion,
Expand Down Expand Up @@ -214,3 +215,64 @@ if (false && true) {
});
});
});

describe("generateModuleMetadataInjectorCode", () => {
it("generates code with empty metadata object", () => {
const generatedCode = generateModuleMetadataInjectorCode({});
expect(generatedCode).toMatchInlineSnapshot(`
"{
var _sentryModuleMetadataGlobal =
typeof window !== \\"undefined\\"
? window
: typeof global !== \\"undefined\\"
? global
: typeof self !== \\"undefined\\"
? self
: {};
_sentryModuleMetadataGlobal._sentryModuleMetadata =
_sentryModuleMetadataGlobal._sentryModuleMetadata || {};
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack] =
Object.assign(
{},
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack],
{}
);
}"
`);
});

it("generates code with metadata object", () => {
const generatedCode = generateModuleMetadataInjectorCode({
"file1.js": {
foo: "bar",
},
"file2.js": {
bar: "baz",
},
});
expect(generatedCode).toMatchInlineSnapshot(`
"{
var _sentryModuleMetadataGlobal =
typeof window !== \\"undefined\\"
? window
: typeof global !== \\"undefined\\"
? global
: typeof self !== \\"undefined\\"
? self
: {};
_sentryModuleMetadataGlobal._sentryModuleMetadata =
_sentryModuleMetadataGlobal._sentryModuleMetadata || {};
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack] =
Object.assign(
{},
_sentryModuleMetadataGlobal._sentryModuleMetadata[new _sentryModuleMetadataGlobal.Error().stack],
{\\"file1.js\\":{\\"foo\\":\\"bar\\"},\\"file2.js\\":{\\"bar\\":\\"baz\\"}}
);
}"
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ function checkBundle(bundlePath1: string, bundlePath2: string): string[] {
expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/)
);

expect(Object.keys(debugIdMap1)[0]).toContain("Error");

const process2Output = childProcess.execSync(`node ${bundlePath2}`, { encoding: "utf-8" });
const debugIdMap2 = JSON.parse(process2Output) as Record<string, string>;
const debugIds2 = Object.values(debugIdMap2);
Expand All @@ -21,6 +23,8 @@ function checkBundle(bundlePath1: string, bundlePath2: string): string[] {
expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/)
);

expect(Object.keys(debugIdMap2)[0]).toContain("Error");

expect(debugIds1).not.toEqual(debugIds2);

return [...debugIds1, ...debugIds2];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ function checkBundle(bundlePath: string): void {
expect(Object.values(map)).toHaveLength(1);
// The value should be the expected metadata
expect(Object.values(map)).toEqual([{ team: "frontend" }]);

// The key is the stack trace of the error thrown in the file
expect(Object.keys(map)[0]).toContain("Error");
expect(Object.keys(map)[0]).toContain("bundle.js");
}

describe("metadata injection", () => {
Expand Down

0 comments on commit 22b9a47

Please sign in to comment.