Files
ISA-Frontend/.claude/skills/logging/references/troubleshooting.md
Lorenz Hilpert 43e4a6bf64 ♻️ refactor(claude): migrate skills to new skill-creator format
Recreate all 11 skills using the updated skill-creator tooling:
- api-sync, arch-docs, architecture-validator, css-animations
- git-workflow, library-creator, logging, state-patterns
- tailwind, template-standards, test-migration

Key changes:
- Updated YAML frontmatter structure
- Reorganized logging references into references/ subdirectory
- Applied progressive disclosure patterns where applicable
2025-12-11 12:27:15 +01:00

5.1 KiB

Logging Troubleshooting

1. Logs Not Appearing

Problem: Logger called but nothing in console.

Solutions:

// Check log level
provideLogging(
  withLogLevel(isDevMode() ? LogLevel.Debug : LogLevel.Warn)
)

// Add sink
provideLogging(
  withLogLevel(LogLevel.Debug),
  withSink(ConsoleLogSink) // Required!
)

// Verify configuration in app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideLogging(...) // Must be present
  ]
};

2. NullInjectorError

Error: NullInjectorError: No provider for LoggingService!

Solution:

// app.config.ts
import { provideLogging, withLogLevel, withSink,
         LogLevel, ConsoleLogSink } from '@isa/core/logging';

export const appConfig: ApplicationConfig = {
  providers: [
    provideLogging(
      withLogLevel(LogLevel.Debug),
      withSink(ConsoleLogSink)
    )
  ]
};

3. Context Not Showing

Problem: Context passed but doesn't appear.

Check:

// ✅ Both work:
this.#logger.info('Message', () => ({ id: '123' })); // Function
this.#logger.info('Message', { id: '123' });          // Object

// ❌ Common mistake:
const ctx = { id: '123' };
this.#logger.info('Message', ctx); // Actually works!

// Verify hierarchical merge:
// Global → Component → Instance → Message

4. Performance Issues

Problem: Slow when debug logging enabled.

Solutions:

// ✅ Use lazy evaluation
this.#logger.debug('Data', () => ({
  expensive: this.compute() // Only if debug enabled
}));

// ✅ Reduce log frequency
this.#logger.debug('Batch', () => ({
  count: items.length // Not each item
}));

// ✅ Increase production level
provideLogging(
  withLogLevel(isDevMode() ? LogLevel.Debug : LogLevel.Warn)
)

5. Error Object Not Logged

Problem: Error shows as [object Object].

Solution:

// ❌ Wrong
this.#logger.error('Failed', { error }); // Don't wrap in object

// ✅ Correct
this.#logger.error('Failed', error as Error, () => ({
  additionalContext: 'value'
}));

6. TypeScript Errors

Error: Type 'X' is not assignable to 'MaybeLoggerContextFn'

Solution:

// ❌ Wrong type
this.#logger.info('Message', 'string'); // Invalid

// ✅ Correct types
this.#logger.info('Message', { key: 'value' });
this.#logger.info('Message', () => ({ key: 'value' }));

7. Logs in Tests

Problem: Test output cluttered with logs.

Solutions:

// Mock logging service
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { LoggingService } from '@isa/core/logging';

const createComponent = createComponentFactory({
  component: MyComponent,
  mocks: [LoggingService] // Mocks all log methods
});

// Or disable in tests
TestBed.configureTestingModule({
  providers: [
    provideLogging(withLogLevel(LogLevel.Off))
  ]
});

8. Undefined Property Error

Error: Cannot read property 'X' of undefined

Problem: Accessing uninitialized property in logger context.

Solutions:

// ❌ Problem
#logger = logger(() => ({
  userId: this.userService.currentUserId // May be undefined
}));

// ✅ Solution 1: Optional chaining
#logger = logger(() => ({
  userId: this.userService?.currentUserId ?? 'unknown'
}));

// ✅ Solution 2: Delay access
ngOnInit() {
  this.#logger.info('Init', () => ({
    userId: this.userService.currentUserId // Safe here
  }));
}

9. Circular Dependency

Error: NG0200: Circular dependency in DI detected

Cause: Service A ← → Service B both inject LoggingService.

Solution:

// ❌ Creates circular dependency
constructor(private loggingService: LoggingService) {}

// ✅ Use factory (no circular dependency)
#logger = logger({ service: 'MyService' });

10. Custom Sink Not Working

Problem: Sink registered but never called.

Solutions:

// ✅ Correct registration
provideLogging(
  withSink(MySink) // Add to config
)

// ✅ Correct signature
export class MySink implements Sink {
  log(
    level: LogLevel,
    message: string,
    context?: LoggerContext,
    error?: Error
  ): void {
    // Implementation
  }
}

// ✅ Sink function must return function
export const mySinkFn: SinkFn = () => {
  const http = inject(HttpClient);
  return (level, message, context, error) => {
    // Implementation
  };
};

Quick Diagnostics

// Enable all logs temporarily
provideLogging(withLogLevel(LogLevel.Trace))

// Check imports
import { logger } from '@isa/core/logging'; // ✅ Correct
import { logger } from '@isa/core/logging/src/lib/logger.factory'; // ❌ Wrong

// Verify console filters in browser DevTools
// Ensure Info, Debug, Warnings are enabled

Common Error Messages

Error Cause Fix
NullInjectorError: LoggingService Missing config Add provideLogging()
Type 'X' not assignable Wrong context type Use object or function
Cannot read property 'X' Undefined property Use optional chaining
Circular dependency Service injection Use logger() factory
Stack overflow Infinite loop in context Don't call logger in context