#!/usr/bin/env npx tsx /** * Test script to verify Bugsink error tracking is working. * * This script sends test events directly to Bugsink using the Sentry store API. * We use curl/fetch instead of the Sentry SDK because SDK v8+ has strict DSN * validation that rejects HTTP URLs (Bugsink uses HTTP locally). * * Usage: * npx tsx scripts/test-bugsink.ts * * Or with environment override: * SENTRY_DSN=http://...@localhost:8000/1 npx tsx scripts/test-bugsink.ts */ // Configuration - parse DSN to extract components const DSN = process.env.SENTRY_DSN || 'http://59a58583-e869-7697-f94a-cfa0337676a8@localhost:8000/1'; const ENVIRONMENT = process.env.SENTRY_ENVIRONMENT || 'test'; // Parse DSN: http://@/ function parseDsn(dsn: string) { const match = dsn.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/); if (!match) { throw new Error(`Invalid DSN format: ${dsn}`); } return { protocol: match[1], publicKey: match[2], host: match[3], projectId: match[4], }; } const dsnParts = parseDsn(DSN); const STORE_URL = `${dsnParts.protocol}://${dsnParts.host}/api/${dsnParts.projectId}/store/`; console.log('='.repeat(60)); console.log('Bugsink/Sentry Test Script'); console.log('='.repeat(60)); console.log(`DSN: ${DSN}`); console.log(`Store URL: ${STORE_URL}`); console.log(`Public Key: ${dsnParts.publicKey}`); console.log(`Environment: ${ENVIRONMENT}`); console.log(''); // Generate a UUID for event_id function generateEventId(): string { return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/x/g, () => Math.floor(Math.random() * 16).toString(16), ); } // Send an event to Bugsink via the Sentry store API async function sendEvent( event: Record, ): Promise<{ success: boolean; status: number }> { const response = await fetch(STORE_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Sentry-Auth': `Sentry sentry_version=7, sentry_client=test-bugsink/1.0, sentry_key=${dsnParts.publicKey}`, }, body: JSON.stringify(event), }); return { success: response.ok, status: response.status, }; } async function main() { console.log('[Test] Sending test events to Bugsink...\n'); try { // Test 1: Send an error event const errorEventId = generateEventId(); console.log(`[Test 1] Sending error event (ID: ${errorEventId})...`); const errorEvent = { event_id: errorEventId, timestamp: new Date().toISOString(), platform: 'node', level: 'error', logger: 'test-bugsink.ts', environment: ENVIRONMENT, server_name: 'flyer-crawler-dev', message: 'BugsinkTestError: This is a test error from test-bugsink.ts script', exception: { values: [ { type: 'BugsinkTestError', value: 'This is a test error from test-bugsink.ts script', stacktrace: { frames: [ { filename: 'scripts/test-bugsink.ts', function: 'main', lineno: 42, colno: 10, in_app: true, }, ], }, }, ], }, tags: { test: 'true', source: 'test-bugsink.ts', }, }; const errorResult = await sendEvent(errorEvent); console.log( ` Result: ${errorResult.success ? 'SUCCESS' : 'FAILED'} (HTTP ${errorResult.status})`, ); // Test 2: Send an info message const messageEventId = generateEventId(); console.log(`[Test 2] Sending info message (ID: ${messageEventId})...`); const messageEvent = { event_id: messageEventId, timestamp: new Date().toISOString(), platform: 'node', level: 'info', logger: 'test-bugsink.ts', environment: ENVIRONMENT, server_name: 'flyer-crawler-dev', message: 'Test info message from test-bugsink.ts - Bugsink is working!', tags: { test: 'true', source: 'test-bugsink.ts', }, }; const messageResult = await sendEvent(messageEvent); console.log( ` Result: ${messageResult.success ? 'SUCCESS' : 'FAILED'} (HTTP ${messageResult.status})`, ); // Summary console.log(''); console.log('='.repeat(60)); if (errorResult.success && messageResult.success) { console.log('SUCCESS! Both test events were accepted by Bugsink.'); console.log(''); console.log('Check Bugsink UI at http://localhost:8000'); console.log('Look for:'); console.log(' - BugsinkTestError: "This is a test error..."'); console.log(' - Info message: "Test info message from test-bugsink.ts"'); } else { console.log('WARNING: Some events may not have been accepted.'); console.log('Check that Bugsink is running and the DSN is correct.'); process.exit(1); } console.log('='.repeat(60)); } catch (error) { console.error('[Test] Failed to send events:', error); process.exit(1); } } main();