diff --git a/.changeset/little-weeks-join.md b/.changeset/little-weeks-join.md new file mode 100644 index 00000000000..8c652cd7df3 --- /dev/null +++ b/.changeset/little-weeks-join.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Defend against non-serializable params in `invariantWrappers` diff --git a/.size-limits.json b/.size-limits.json index 7d53db26ea2..09bf55362fa 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 39581, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32830 + "dist/apollo-client.min.cjs": 39604, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32852 } diff --git a/src/utilities/globals/__tests__/invariantWrappers.test.ts b/src/utilities/globals/__tests__/invariantWrappers.test.ts index b8f51390944..5dfc03a1362 100644 --- a/src/utilities/globals/__tests__/invariantWrappers.test.ts +++ b/src/utilities/globals/__tests__/invariantWrappers.test.ts @@ -171,3 +171,25 @@ test("base invariant(false, 6, ...), raises fallback", async () => { ) ); }); + +test("base invariant(false, 6, ...) with non-serializable param", async () => { + await using _ = mockErrorMessageHandler(); + + const obj: any = {}; + obj.self = obj; + + expect(() => { + invariant(false, 6, obj); + }).toThrow( + new InvariantError( + "An error occurred! For more details, see the full error text at https://go.apollo.dev/c/err#" + + encodeURIComponent( + JSON.stringify({ + version: "local", + message: 6, + args: [""], + }) + ) + ) + ); +}); diff --git a/src/utilities/globals/invariantWrappers.ts b/src/utilities/globals/invariantWrappers.ts index 81070cbbb7d..28afa134a55 100644 --- a/src/utilities/globals/invariantWrappers.ts +++ b/src/utilities/globals/invariantWrappers.ts @@ -117,9 +117,15 @@ declare global { } function stringify(arg: any) { - return typeof arg == "string" ? arg : ( - stringifyForDisplay(arg, 2).slice(0, 1000) - ); + if (typeof arg == "string") { + return arg; + } + + try { + return stringifyForDisplay(arg, 2).slice(0, 1000); + } catch { + return ""; + } } function getHandledErrorMsg(