From e7ae570459a9219ec3c9d477032b22fd9b7c8f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Beteg=C3=B3n?= Date: Wed, 23 Sep 2026 15:48:46 +0200 Subject: [PATCH] fix(react-native): handle unreadable sourcemap reports --- .../cli/src/commands/react-native/xcode.ts | 10 +++-- .../test/commands/react-native/xcode.test.ts | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/react-native/xcode.ts b/packages/cli/src/commands/react-native/xcode.ts index 89a976c79a..697b296274 100644 --- a/packages/cli/src/commands/react-native/xcode.ts +++ b/packages/cli/src/commands/react-native/xcode.ts @@ -240,9 +240,13 @@ function runWrappedBuild( const status = runScript(script, scriptArgs, env); - const report = JSON.parse( - readFileSync(reportPath, "utf-8") - ) as SourceMapReport; + let report: SourceMapReport; + try { + report = JSON.parse(readFileSync(reportPath, "utf-8")) as SourceMapReport; + } catch (error) { + log.debug("Failed to read sourcemap report file", error); + return { status, pair: null }; + } if (!(report.packager_bundle_path && report.packager_sourcemap_path)) { return { status, pair: null }; } diff --git a/packages/cli/test/commands/react-native/xcode.test.ts b/packages/cli/test/commands/react-native/xcode.test.ts index 9937e859dd..1edcca1950 100644 --- a/packages/cli/test/commands/react-native/xcode.test.ts +++ b/packages/cli/test/commands/react-native/xcode.test.ts @@ -158,6 +158,45 @@ describe("react-native xcode", () => { expect(sourcemaps.uploadSourcemaps).not.toHaveBeenCalled(); }); + test.each([ + ["missing", 0], + ["missing", 7], + ["malformed", 0], + ["malformed", 7], + ] as const)("skips upload for a %s report and preserves build status %i", async (reportState, status) => { + spawnMock.mockImplementation( + ( + _cmd: string, + _args: readonly string[] | undefined, + spawnOpts?: { env?: NodeJS.ProcessEnv } + ) => { + const reportPath = spawnOpts?.env?.SENTRY_RN_SOURCEMAP_REPORT; + if (reportPath) { + if (reportState === "missing") { + rmSync(reportPath); + } else { + writeFileSync(reportPath, '{"packager_bundle_path":'); + } + } + return { + status, + stdout: "", + stderr: "", + pid: 1, + output: [], + signal: null, + }; + } + ); + + const ctx = createContext({ CONFIGURATION: "Release" }); + const func = await xcodeCommand.loader(); + await func.call(ctx, { "build-script": script }); + + expect(ctx.process.exitCode).toBe(status === 0 ? undefined : status); + expect(sourcemaps.uploadSourcemaps).not.toHaveBeenCalled(); + }); + test("warns and skips upload when the build produced no sourcemaps", async () => { spawnMock.mockImplementation( (