Skip to content

Commit 96a6601

Browse files
cursoragentclaude
andcommitted
fix(sveltekit): improve error handling in source map cleaning
- Changed overly broad catch block to check for ENOENT errors specifically - Added debug logging for unexpected errors during source map cleaning - Added regression tests for error handling in source map cleaning logic Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent fe4087a commit 96a6601

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

packages/sveltekit/src/vite/sourceMaps.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,12 @@ export async function makeCustomSentryVitePlugins(
221221
'',
222222
);
223223
await fs.promises.writeFile(mapFile, cleanedMapContent);
224-
} catch {
225-
// Map file doesn't exist, nothing to clean
224+
} catch (e) {
225+
const isKnownError = e instanceof Error && e.message.includes('ENOENT: no such file or directory, open');
226+
if (debug && !isKnownError) {
227+
// eslint-disable-next-line no-console
228+
console.error('[Source Maps Plugin] error while cleaning source map', mapFile, e);
229+
}
226230
}
227231
}
228232

packages/sveltekit/test/vite/sourceMaps.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { sentryVitePlugin } from '@sentry/vite-plugin';
2+
import * as fs from 'fs';
23
import type { Plugin } from 'vite';
34
import * as vite from 'vite';
45
import { beforeEach, describe, expect, it, vi } from 'vitest';
@@ -37,6 +38,20 @@ vi.mock('sorcery', async () => {
3738
};
3839
});
3940

41+
vi.mock('fs', async () => {
42+
const actual = (await vi.importActual('fs')) as typeof fs;
43+
return {
44+
...actual,
45+
existsSync: vi.fn(actual.existsSync),
46+
readdirSync: vi.fn(actual.readdirSync),
47+
promises: {
48+
...actual.promises,
49+
readFile: vi.fn(actual.promises.readFile),
50+
writeFile: vi.fn(actual.promises.writeFile),
51+
},
52+
};
53+
});
54+
4055
beforeEach(() => {
4156
vi.clearAllMocks();
4257
});
@@ -212,6 +227,57 @@ describe('makeCustomSentryVitePlugins()', () => {
212227
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to upload source maps'));
213228
expect(consoleLogSpy).toHaveBeenCalled();
214229
});
230+
231+
it('handles missing map files gracefully during source map cleaning', async () => {
232+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
233+
234+
vi.mocked(fs.existsSync).mockReturnValueOnce(true);
235+
vi.mocked(fs.readdirSync).mockReturnValueOnce([{ name: 'test.js', isDirectory: () => false } as any]);
236+
vi.mocked(fs.promises.readFile).mockRejectedValueOnce(
237+
Object.assign(new Error('ENOENT: no such file or directory, open'), { code: 'ENOENT' }),
238+
);
239+
240+
const plugin = await getSentryViteSubPlugin('sentry-sveltekit-debug-id-upload-plugin');
241+
242+
// @ts-expect-error this function exists!
243+
plugin.configResolved({ build: { ssr: true } });
244+
// @ts-expect-error this function exists!
245+
await plugin.closeBundle();
246+
247+
expect(consoleErrorSpy).not.toHaveBeenCalled();
248+
});
249+
250+
it('logs unexpected errors during source map cleaning when debug is enabled', async () => {
251+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
252+
253+
vi.mocked(fs.existsSync).mockReturnValueOnce(true);
254+
vi.mocked(fs.readdirSync).mockReturnValueOnce([{ name: 'test.js', isDirectory: () => false } as any]);
255+
vi.mocked(fs.promises.readFile).mockRejectedValueOnce(new Error('Permission denied'));
256+
257+
const plugins = await makeCustomSentryVitePlugins(
258+
{
259+
authToken: 'token',
260+
org: 'org',
261+
project: 'project',
262+
adapter: 'other',
263+
debug: true,
264+
},
265+
{ kit: {} },
266+
);
267+
268+
const plugin = plugins.find(p => p.name === 'sentry-sveltekit-debug-id-upload-plugin');
269+
270+
// @ts-expect-error this function exists!
271+
plugin.configResolved({ build: { ssr: true } });
272+
// @ts-expect-error this function exists!
273+
await plugin.closeBundle();
274+
275+
expect(consoleErrorSpy).toHaveBeenCalledWith(
276+
expect.stringContaining('[Source Maps Plugin] error while cleaning source map'),
277+
expect.any(String),
278+
expect.any(Error),
279+
);
280+
});
215281
});
216282

217283
describe('_getUpdatedSourceMapSettings', () => {

0 commit comments

Comments
 (0)