flutter
dart
npx skills add dhruvanbhalara/skills --skill flutter-debugging
Logging
- Use a centralized
AppLogger class for all logging — NEVER use print() or raw debugPrint()
- Define log levels:
verbose, debug, info, warning, error, fatal
- In dev flavor: log everything (verbose and above)
- In staging: log info and above
- In production: log warning and above only, route to Crashlytics
- Include context in logs:
AppLogger.error('Failed to fetch user', error: e, stackTrace: st)
- NEVER log sensitive data (passwords, tokens, PII) at any level
- Use Widget Inspector to debug layout issues and identify unnecessary rebuilds
- Use Performance Overlay (
showPerformanceOverlay: true) to monitor frame rates
- Use Timeline View to identify jank — target 16ms per frame (60fps)
- Use Memory View to detect memory leaks and monitor allocation patterns
- Use Network Profiler to inspect Dio requests/responses during development
Debugging Strategies
- Layout Issues: Use
debugPaintSizeEnabled = true to visualize widget boundaries
- Overflow Errors: Check
RenderFlex overflowed — use Expanded, Flexible, or constrain dimensions
- Unbounded Height: Wrap
ListView in SizedBox or use shrinkWrap: true with NeverScrollableScrollPhysics
- Rebuild Tracking: Add
debugPrint('$runtimeType rebuild') temporarily to identify excessive rebuilds — remove before commit
- Async Errors: Always catch and log errors in
try-catch blocks with stack traces
- Use
assert() for development-time invariant checks that are stripped in release builds
Memory Management
- Dispose ALL controllers, subscriptions,
Timer, and AnimationController in dispose()
- Use
late initialization in initState() — never inline-initialize disposable objects
- Use
WeakReference for caches that should not prevent garbage collection
- Profile memory with DevTools Memory tab — watch for monotonically increasing allocations
- Watch for common leaks: undisposed listeners, closures capturing
BuildContext, global streams without cancellation
Error Boundaries
- Route errors to Crashlytics in staging/prod (
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError)
- Set
FlutterError.onError and PlatformDispatcher.instance.onError to catch framework and async errors
- Wrap critical widget subtrees in custom error boundary widgets that show fallback UI instead of red screens
- In release mode: NEVER show stack traces to users — show user-friendly error messages only