ArchitectureHard50 XP4 min read
How do you handle errors across layers in a Flutter Clean Architecture app?
TL;DR: Use a sealed Result<T>/Either<Failure, Success> type in the domain layer. Repository implementations catch exceptions and convert them to typed Failure objects. The UI layer pattern-matches on Success vs Failure without catching exceptions.
Full Answer
Throwing exceptions across architectural layers breaks encapsulation. A DioException from the data layer should not propagate into the domain or presentation layer raw.
The Failure Hierarchy
- ▸NetworkFailure: Dio timeout, connection error, 5xx
- ▸ServerFailure: 4xx with specific error body
- ▸CacheFailure: Local database read/write failed
- ▸AuthFailure: 401 — token expired or invalid
🎯
Define Failure as a sealed class in the Domain layer (not Data). Data maps exceptions to Failures. Presentation maps Failures to user-readable messages.
Code Examples
dartResult type with sealed Failure
Output
// No exceptions cross layer boundaries // Bloc receives typed Failure, not raw DioException
Common Mistakes
- ✗Catching Exception (base class) instead of specific types — loses error context
- ✗Putting Failure definitions in the Data layer — Domain should define the contract, Data implements it
Interview Tip
💡
Show the full flow: DioException → NetworkFailure (in data) → QuizError state (in bloc) → error snackbar (in UI). Each layer only knows its own type.
#error-handling#either#result-type#failure#exception