# Time Safari Architecture — Examples and Testing > **Agent role**: Reference this file for architectural examples and testing patterns when working with TimeSafari architecture. ## Error Handling Patterns ### Global Error Handler ```typescript // main.ts app.config.errorHandler = (err, instance, info) => { const componentName = instance?.$options?.name || 'Unknown'; logger.error(`[${componentName}] Vue error`, err, info); }; window.addEventListener('unhandledrejection', (event) => { logger.error('[Global] Unhandled promise rejection', event.reason); }); ``` ### Platform-Specific Error Wrapping ```typescript // services/platforms/CapacitorPlatformService.ts export class CapacitorPlatformService { async getFileContents(path: string): Promise { try { const result = await Filesystem.readFile({ path: path, encoding: 'utf8' }); return result.data; } catch (error) { logger.error('[Capacitor API Error] Failed to read file', error, path); throw new Error(`Failed to read file: ${path}`); } } } ``` ## Testing Patterns ### Platform-Specific Test Skipping ```typescript // tests/QRScanner.test.ts describe('QRScanner Service', () => { test('should start scanning on web', async () => { test.skip(process.env.VITE_PLATFORM !== 'web', 'Web-only test'); const scanner = new WebInlineQRScanner(); await scanner.startScanning(); // Assert scanning started }); test('should start scanning on mobile', async () => { test.skip(process.env.VITE_PLATFORM !== 'capacitor', 'Mobile-only test'); const scanner = new CapacitorQRScanner(); await scanner.startScanning(); // Assert scanning started }); }); ``` ### Mock Service Testing ```typescript // tests/mocks/QRScannerMock.ts export class QRScannerMock implements QRScannerService { private isScanning = false; private listeners: Map = new Map(); async startScanning(): Promise { this.isScanning = true; this.emit('scanningStarted'); } async stopScanning(): Promise { this.isScanning = false; this.emit('scanningStopped'); } addListener(event: string, callback: Function): void { if (!this.listeners.has(event)) { this.listeners.set(event, []); } this.listeners.get(event)!.push(callback); } removeListener(event: string, callback: Function): void { const callbacks = this.listeners.get(event); if (callbacks) { const index = callbacks.indexOf(callback); if (index > -1) { callbacks.splice(index, 1); } } } private emit(event: string, ...args: any[]): void { const callbacks = this.listeners.get(event); if (callbacks) { callbacks.forEach(callback => callback(...args)); } } getScanningState(): boolean { return this.isScanning; } } ``` ## Integration Examples ### Service Composition ```typescript // services/QRScannerService.ts export class QRScannerService { constructor( private platformService: PlatformService, private notificationService: NotificationService ) {} async startScanning(): Promise { try { await this.platformService.startCamera(); this.notificationService.show('Camera started'); } catch (error) { this.notificationService.showError('Failed to start camera'); throw error; } } } ``` ### Component Integration ```typescript // components/QRScannerDialog.vue export default class QRScannerDialog extends Vue { @Inject() private qrScannerService!: QRScannerService; async mounted() { try { await this.qrScannerService.startScanning(); } catch (error) { this.$notify.error('Failed to start scanner'); } } beforeDestroy() { this.qrScannerService.stopScanning(); } } ``` ## Best Practices ### Service Design - Keep services focused and single-purpose - Use dependency injection for service composition - Implement proper error handling and logging - Provide clear interfaces and contracts ### Testing Strategy - Test platform-specific behavior separately - Use mocks for external dependencies - Test error conditions and edge cases - Validate service contracts and interfaces ### Error Handling - Log errors with appropriate context - Provide user-friendly error messages - Implement graceful degradation - Handle platform-specific error scenarios --- **See also**: - `.cursor/rules/app/architectural_decision_record.mdc` for core architecture principles - `.cursor/rules/app/architectural_implementation.mdc` for implementation details - `.cursor/rules/app/architectural_patterns.mdc` for core patterns **Status**: Active examples and testing guide **Priority**: Medium **Estimated Effort**: Ongoing reference **Dependencies**: architectural_patterns.mdc **Stakeholders**: Development team, Testing team ## Model Implementation Checklist ### Before Architectural Examples - [ ] **Pattern Selection**: Choose appropriate architectural pattern for the use case - [ ] **Service Design**: Plan service structure and dependencies - [ ] **Testing Strategy**: Plan testing approach for the example - [ ] **Error Handling**: Plan error handling and logging strategy ### During Architectural Examples - [ ] **Service Implementation**: Implement focused, single-purpose services - [ ] **Dependency Injection**: Use proper dependency injection patterns - [ ] **Error Handling**: Implement proper error handling and logging - [ ] **Interface Design**: Provide clear interfaces and contracts ### After Architectural Examples - [ ] **Testing Execution**: Test platform-specific behavior separately - [ ] **Service Validation**: Validate service contracts and interfaces - [ ] **Error Testing**: Test error conditions and edge cases - [ ] **Documentation**: Update architectural examples documentation