@nestjsvn/swagger-sse
Version:
OpenAPI documentation and interactive Swagger UI for NestJS Server-Sent Events endpoints
593 lines (466 loc) • 13.6 kB
Markdown
# 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**