UNPKG

@nestjsvn/swagger-sse

Version:

OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints

593 lines (466 loc) 13.6 kB
# Troubleshooting Guide This guide helps you diagnose and fix common issues with `@nestjsvn/swagger-sse`. ## Table of Contents 1. [Installation Issues](#installation-issues) 2. [Configuration Problems](#configuration-problems) 3. [SSE Connection Issues](#sse-connection-issues) 4. [Plugin Problems](#plugin-problems) 5. [UI Display Issues](#ui-display-issues) 6. [Performance Issues](#performance-issues) 7. [Browser Compatibility](#browser-compatibility) 8. [Debugging Tips](#debugging-tips) ## Installation Issues ### Peer Dependency Warnings **Problem**: npm warns about missing peer dependencies. ``` npm WARN @nestjsvn/swagger-sse@1.0.0 requires a peer of @nestjs/common@^10.0.0 but none is installed. ``` **Solution**: Install the required peer dependencies: ```bash npm install @nestjs/common @nestjs/swagger ``` **Supported Versions**: - `@nestjs/common`: ^9.0.0 || ^10.0.0 || ^11.0.0 - `@nestjs/swagger`: ^7.0.0 || ^8.0.0 || ^11.0.0 ### TypeScript Compilation Errors **Problem**: TypeScript compilation fails with decorator errors. ``` error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. ``` **Solution**: Enable decorator support in `tsconfig.json`: ```json { "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } } ``` ### Module Resolution Issues **Problem**: Cannot find module '@nestjsvn/swagger-sse'. **Solutions**: 1. **Clear node_modules and reinstall**: ```bash rm -rf node_modules package-lock.json npm install ``` 2. **Check import paths**: ```typescript // Correct import { ApiSse } from '@nestjsvn/swagger-sse'; import { setupSsePlugin } from '@nestjsvn/swagger-sse'; // Plugin import // In nest-cli.json: "@nestjsvn/swagger-sse/plugin" ``` 3. **Verify package installation**: ```bash npm list @nestjsvn/swagger-sse ``` ## Configuration Problems ### setupSsePlugin Not Working **Problem**: Swagger UI loads but SSE features are missing. **Common Causes & Solutions**: 1. **Incorrect setup order**: ```typescript // Wrong SwaggerModule.setup(app, document, 'api-docs'); setupSsePlugin(app, document, 'api-docs'); // Correct setupSsePlugin(app, document, 'api-docs'); ``` 2. **Missing document parameter**: ```typescript // Wrong const document = SwaggerModule.createDocument(app, config); setupSsePlugin(app, null, 'api-docs'); // null document // Correct const document = SwaggerModule.createDocument(app, config); setupSsePlugin(app, document, 'api-docs'); ``` 3. **Path mismatch**: ```typescript // Ensure paths match setupSsePlugin(app, document, 'api-docs'); // Serves at /api-docs ``` ### @ApiSse Decorator Not Applied **Problem**: SSE endpoints appear as regular endpoints in Swagger UI. **Diagnostic Steps**: 1. **Check decorator import**: ```typescript import { ApiSse } from '@nestjsvn/swagger-sse'; // Correct ``` 2. **Verify decorator placement**: ```typescript @Controller('events') export class EventsController { @Sse('stream') @ApiSse({ // Must be before method events: { 'test': TestDto } }) streamEvents(): Observable<MessageEvent> { // ... } } ``` 3. **Check events configuration**: ```typescript @ApiSse({ events: { 'event-name': EventDto, // Must be valid class/type } }) ``` ## SSE Connection Issues ### Connection Immediately Fails **Problem**: SSE connection shows error state immediately. **Diagnostic Steps**: 1. **Check endpoint accessibility**: ```bash curl -H "Accept: text/event-stream" http://localhost:3000/events/stream ``` 2. **Verify CORS configuration**: ```typescript // In main.ts app.enableCors({ origin: ['http://localhost:3000'], // Add your frontend URL credentials: true, }); ``` 3. **Check endpoint implementation**: ```typescript @Sse('stream') streamEvents(): Observable<MessageEvent> { return interval(1000).pipe( map(i => ({ data: JSON.stringify({ message: `Event ${i}` }), type: 'test-event', } as MessageEvent)) ); } ``` ### Events Not Appearing **Problem**: Connection succeeds but no events are displayed. **Common Issues**: 1. **Incorrect MessageEvent format**: ```typescript // Wrong return of({ message: 'test' }); // Correct return of({ data: JSON.stringify({ message: 'test' }), type: 'test-event', } as MessageEvent); ``` 2. **Observable not emitting**: ```typescript // Add debugging streamEvents(): Observable<MessageEvent> { return interval(1000).pipe( tap(() => console.log('Emitting event')), // Debug log map(i => ({ data: JSON.stringify({ count: i }), type: 'counter', } as MessageEvent)) ); } ``` 3. **Event type mismatch**: ```typescript @ApiSse({ events: { 'counter': CounterDto, // Must match event type } }) streamEvents(): Observable<MessageEvent> { return interval(1000).pipe( map(i => ({ data: JSON.stringify({ count: i }), type: 'counter', // Must match key in events } as MessageEvent)) ); } ``` ### Connection Drops Frequently **Problem**: SSE connection disconnects and reconnects repeatedly. **Solutions**: 1. **Check server stability**: ```typescript // Add error handling streamEvents(): Observable<MessageEvent> { return interval(1000).pipe( map(i => ({ /* event data */ })), catchError(error => { console.error('Stream error:', error); return EMPTY; // Or retry logic }) ); } ``` 2. **Implement keep-alive**: ```typescript streamEvents(): Observable<MessageEvent> { const keepAlive = interval(30000).pipe( map(() => ({ data: JSON.stringify({ type: 'keep-alive' }), type: 'keep-alive', } as MessageEvent)) ); const dataEvents = this.getDataStream(); return merge(keepAlive, dataEvents); } ``` 3. **Check network configuration**: - Proxy settings - Load balancer configuration - Firewall rules ## Plugin Problems ### CLI Plugin Not Working **Problem**: Automatic documentation generation doesn't work. **Diagnostic Steps**: 1. **Verify nest-cli.json configuration**: ```json { "compilerOptions": { "plugins": [ "@nestjs/swagger", // Must be first { "name": "@nestjsvn/swagger-sse/plugin", "options": { "eventNamingConvention": "kebab-case" } } ] } } ``` 2. **Check plugin loading**: ```bash # Build with verbose output npm run build -- --verbose ``` 3. **Verify TypeScript version compatibility**: ```bash npm list typescript # Should be 4.5+ (5.0+ recommended) ``` ### Plugin Transformation Errors **Problem**: Build fails with plugin-related errors. **Common Solutions**: 1. **Update TypeScript**: ```bash npm install typescript@latest ``` 2. **Check for conflicting plugins**: ```json // Remove conflicting plugins temporarily { "compilerOptions": { "plugins": [ "@nestjs/swagger", "@nestjsvn/swagger-sse/plugin" // Remove other plugins to test ] } } ``` 3. **Disable plugin temporarily**: ```json // Test without plugin { "compilerOptions": { "plugins": [ "@nestjs/swagger" // Comment out SSE plugin ] } } ``` ## UI Display Issues ### SSE Controls Not Visible **Problem**: Swagger UI loads but SSE-specific controls are missing. **Solutions**: 1. **Check browser console for errors**: ```javascript // Open browser dev tools and check for: // - JavaScript errors // - Failed resource loads // - CSS issues ``` 2. **Verify plugin assets are loaded**: ```bash # Check if these URLs are accessible: # http://localhost:3000/api-docs/swagger-sse-plugin.js # http://localhost:3000/api-docs/swagger-sse-plugin.css ``` 3. **Clear browser cache**: ```bash # Hard refresh: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac) ``` ### Styling Issues **Problem**: SSE UI elements appear but are poorly styled. **Solutions**: 1. **Check CSS conflicts**: ```css /* Add custom CSS to fix conflicts */ .sse-plugin-container { z-index: 1000 !important; } ``` 2. **Override default styles**: ```typescript setupSsePlugin(app, document, 'api-docs', { customCss: ` .sse-event-log { max-height: 400px; overflow-y: auto; } `, }); ``` ## Performance Issues ### Slow Event Processing **Problem**: UI becomes sluggish with many events. **Solutions**: 1. **Implement event log limits**: ```typescript // In your SSE UI component const MAX_EVENTS = 100; const events = eventLog.slice(-MAX_EVENTS); ``` 2. **Use event filtering**: ```typescript @ApiSse({ events: { 'high-priority': HighPriorityDto, 'low-priority': LowPriorityDto, } }) streamEvents(@Query('priority') priority?: string): Observable<MessageEvent> { return this.eventService.getFilteredEvents(priority); } ``` 3. **Optimize event frequency**: ```typescript // Reduce frequency for high-volume streams streamEvents(): Observable<MessageEvent> { return this.dataSource.pipe( throttleTime(100), // Limit to 10 events/second map(data => ({ /* event */ })) ); } ``` ### Memory Leaks **Problem**: Memory usage increases over time. **Solutions**: 1. **Implement proper cleanup**: ```typescript // In your component ngOnDestroy() { this.eventSource?.close(); this.subscription?.unsubscribe(); } ``` 2. **Limit event history**: ```typescript // Keep only recent events const HISTORY_LIMIT = 50; this.events = this.events.slice(-HISTORY_LIMIT); ``` ## Browser Compatibility ### EventSource Not Supported **Problem**: SSE doesn't work in older browsers. **Solutions**: 1. **Add EventSource polyfill**: ```html <script src="https://cdn.jsdelivr.net/npm/event-source-polyfill@1.0.25/src/eventsource.min.js"></script> ``` 2. **Feature detection**: ```javascript if (typeof EventSource === 'undefined') { console.warn('EventSource not supported'); // Show fallback UI } ``` ### CORS Issues in Safari **Problem**: SSE connections fail in Safari due to CORS. **Solution**: Configure CORS properly: ```typescript app.enableCors({ origin: true, // Or specific origins credentials: true, methods: ['GET', 'POST', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'Cache-Control'], }); ``` ## Debugging Tips ### Enable Debug Logging 1. **Server-side debugging**: ```typescript import { Logger } from '@nestjs/common'; @Controller('events') export class EventsController { private readonly logger = new Logger(EventsController.name); @Sse('stream') streamEvents(): Observable<MessageEvent> { return interval(1000).pipe( tap(() => this.logger.debug('Emitting SSE event')), map(i => ({ /* event */ })) ); } } ``` 2. **Client-side debugging**: ```javascript // In browser console localStorage.setItem('debug', 'swagger-sse:*'); ``` ### Network Analysis 1. **Monitor SSE connections**: ```bash # Use browser dev tools Network tab # Filter by "EventStream" or "text/event-stream" ``` 2. **Test with curl**: ```bash curl -N -H "Accept: text/event-stream" \ -H "Cache-Control: no-cache" \ http://localhost:3000/events/stream ``` ### Common Error Messages | Error | Cause | Solution | |-------|-------|----------| | `Cannot find module '@nestjsvn/swagger-sse'` | Package not installed | `npm install @nestjsvn/swagger-sse` | | `EventSource is not defined` | Browser compatibility | Add EventSource polyfill | | `CORS policy blocks request` | CORS misconfiguration | Configure CORS properly | | `text/event-stream expected` | Wrong content type | Check SSE endpoint implementation | | `Connection failed immediately` | Endpoint not accessible | Verify endpoint URL and server status | ### Getting Help If you're still experiencing issues: 1. **Check existing issues**: [GitHub Issues](https://github.com/nestjsx/swagger-sse/issues) 2. **Create minimal reproduction**: Isolate the problem in a small example 3. **Provide environment details**: - Node.js version - NestJS version - Browser version - Operating system 4. **Include error logs**: Full error messages and stack traces 5. **Share configuration**: Your `nest-cli.json` and setup code ## Preventive Measures ### Code Review Checklist - [ ] `@ApiSse` decorator properly configured - [ ] Event types match between decorator and implementation - [ ] MessageEvent format is correct - [ ] Error handling implemented - [ ] CORS configured if needed - [ ] Plugin configuration is valid - [ ] TypeScript types are properly defined ### Testing Strategy 1. **Unit tests** for SSE endpoints 2. **Integration tests** for Swagger documentation 3. **E2E tests** for browser functionality 4. **Performance tests** for high-volume scenarios ### Monitoring 1. **Log SSE connection events** 2. **Monitor memory usage** 3. **Track error rates** 4. **Measure event processing performance**