Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 60422da644 | |||
| fc6da4e9aa |
@@ -7,14 +7,36 @@ export function fixMdxDataProps(content: string): string {
|
||||
let endIndex = -1;
|
||||
const startObj = dataIndex + 6; // index of the first '{' in 'data={{'
|
||||
|
||||
let inString = false;
|
||||
let isEscaped = false;
|
||||
|
||||
for (let i = startObj; i < fixedContent.length; i++) {
|
||||
if (fixedContent[i] === '{') {
|
||||
openCount++;
|
||||
} else if (fixedContent[i] === '}') {
|
||||
openCount--;
|
||||
if (openCount === 0) {
|
||||
endIndex = i;
|
||||
break;
|
||||
const char = fixedContent[i];
|
||||
|
||||
if (isEscaped) {
|
||||
isEscaped = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === '\\') {
|
||||
isEscaped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === '"') {
|
||||
inString = !inString;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inString) {
|
||||
if (char === '{') {
|
||||
openCount++;
|
||||
} else if (char === '}') {
|
||||
openCount--;
|
||||
if (openCount === 0) {
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ export class GlitchtipErrorReportingService implements ErrorReportingService {
|
||||
tracesSampleRate: this.options.tracesSampleRate ?? 0.1,
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
replaysSessionSampleRate: 0.1,
|
||||
ignoreErrors: [
|
||||
'ChunkLoadError',
|
||||
'Failed to fetch dynamically imported module',
|
||||
'Failed to find Server Action',
|
||||
],
|
||||
});
|
||||
}
|
||||
return Sentry;
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.3.30",
|
||||
"version": "2.3.32",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
47
tests/glitchtip-error-reporting.test.ts
Normal file
47
tests/glitchtip-error-reporting.test.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { GlitchtipErrorReportingService } from '../lib/services/errors/glitchtip-error-reporting-service';
|
||||
|
||||
// Mock the LoggerService
|
||||
const mockLogger = {
|
||||
child: vi.fn().mockReturnThis(),
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
} as any;
|
||||
|
||||
const mockSentryInit = vi.fn();
|
||||
|
||||
vi.mock('@sentry/nextjs', () => ({
|
||||
init: (...args: any[]) => mockSentryInit(...args),
|
||||
captureException: vi.fn(),
|
||||
captureMessage: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('GlitchtipErrorReportingService', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should ignore version drift errors (ChunkLoadError and Server Action) in Sentry config', async () => {
|
||||
// Simulate window to force client-side init behavior instantly
|
||||
const originalWindow = global.window;
|
||||
global.window = {
|
||||
requestIdleCallback: (cb: Function) => cb(),
|
||||
} as any;
|
||||
|
||||
const service = new GlitchtipErrorReportingService({ enabled: true }, mockLogger);
|
||||
|
||||
// Give the dynamic import a moment to resolve
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
expect(mockSentryInit).toHaveBeenCalledOnce();
|
||||
const initCallArgs = mockSentryInit.mock.calls[0][0];
|
||||
|
||||
expect(initCallArgs.ignoreErrors).toBeDefined();
|
||||
expect(initCallArgs.ignoreErrors).toContain('ChunkLoadError');
|
||||
expect(initCallArgs.ignoreErrors).toContain('Failed to find Server Action');
|
||||
|
||||
global.window = originalWindow;
|
||||
});
|
||||
});
|
||||
@@ -8,10 +8,15 @@ describe('MDX Data Props Fixer', () => {
|
||||
|
||||
const result = fixMdxDataProps(mdxInput);
|
||||
|
||||
// The expected output should have the entire JSON object enclosed in data="{...}"
|
||||
// and NO trailing characters left over from the regex truncating early.
|
||||
const expected = `<Block type="productTabs" data="{"content":{"root":{"children":[]}},"id":"123"}" />`;
|
||||
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
it('should not prematurely truncate if } appears inside a string literal', () => {
|
||||
const mdxInput = `<Block type="productTabs" data={{"content":{"text":"}>"}}} />`;
|
||||
const result = fixMdxDataProps(mdxInput);
|
||||
const expected = `<Block type="productTabs" data="{"content":{"text":"}>"}}" />`;
|
||||
expect(result).toBe(expected.replace('>', '>'));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user