- بواسطة x32x01 ||
لو بتشتغل بـ Flutter، أكيد قابلت المشكلة دي 😵💫
كل شوية try-catch في كل مكان… وكود بدأ يبقى صعب يتقري، أصعب يتصان، ومليان Bugs!
الحقيقة إن هندلة الأخطاء (Error Handling) بالطريقة التقليدية ممكن تتحول لفوضى بسرعة… خصوصًا في المشاريع الكبيرة.
لكن في حل أنضف وأقوى بكتير 👇
باستخدام Freezed + Union Types.
ممكن التطبيق ينهار (Crash) بسبب Error مش معمول له Handling!
الفكرة ببساطة:
بدل ما الدالة ترمي Error… هي بترجع نتيجة واحدة من حالتين:
الكلاس ده بقى هو المصدر الوحيد للنتيجة بدل Exceptions.
لاحظ هنا 👀
مفيش رمي Exceptions… كل حاجة راجعة بشكل منظم.
الميزة القوية هنا:
ابعد عن try-catch العشوائية وابدأ استخدم: Freezed + Union Types
هتلاحظ فرق كبير في:
الكود النضيف مش رفاهية… ده استثمار في مستقبل مشروعك.
كل شوية try-catch في كل مكان… وكود بدأ يبقى صعب يتقري، أصعب يتصان، ومليان Bugs!
الحقيقة إن هندلة الأخطاء (Error Handling) بالطريقة التقليدية ممكن تتحول لفوضى بسرعة… خصوصًا في المشاريع الكبيرة.
لكن في حل أنضف وأقوى بكتير 👇
باستخدام Freezed + Union Types.
إيه المشكلة في try-catch التقليدية؟
رغم إن try-catch مهمة، لكن استخدامها العشوائي بيعمل مشاكل زي:- ❌ تكرار الكود في كل مكان
- ❌ نسيان التعامل مع بعض الأخطاء
- ❌ كود غير منظم ومليان تشعبات
- ❌ صعوبة اختبار الكود (Testing)
ممكن التطبيق ينهار (Crash) بسبب Error مش معمول له Handling!
الحل: استخدام Freezed وUnion Types
بدل ما تعتمد على Exceptions، تقدر تستخدم نمط منظم بيسمى Result Pattern.الفكرة ببساطة:
بدل ما الدالة ترمي Error… هي بترجع نتيجة واحدة من حالتين:
- ✅ Success → فيها البيانات
- ❌ Failure → فيها تفاصيل الخطأ
مثال عملي: إنشاء ApiResult باستخدام Freezed
Code:
import 'package:freezed_annotation/freezed_annotation.dart';
part 'api_result.freezed.dart';
@freezed
class ApiResult<T> with _$ApiResult<T> {
const factory ApiResult.success(T data) = Success<T>;
const factory ApiResult.failure(String message) = Failure<T>;
} استخدام ApiResult في API Call
Code:
Future<ApiResult<List<String>>> fetchUsers() async {
try {
final data = await api.getUsers();
return ApiResult.success(data);
} catch (e) {
return ApiResult.failure("حدث خطأ أثناء تحميل البيانات");
}
} مفيش رمي Exceptions… كل حاجة راجعة بشكل منظم.
التعامل مع النتيجة باستخدام .when()
هنا بقى السحر الحقيقي 🔥 Code:
result.when(
success: (data) {
print("Data: $data");
},
failure: (message) {
print("Error: $message");
},
); - 🛡️ Compile-time Safety
- مستحيل تنسى تعالج حالة النجاح أو الفشل
- الـ IDE هيجبرك تتعامل مع كل الحالات
الدمج مع Clean Architecture وCubit
لما تستخدم الطريقة دي مع:- Clean Architecture
- Cubit / Bloc
- فصل كامل بين Logic و UI
- كود قابل للاختبار بسهولة
- إدارة حالات التطبيق بشكل واضح
ليه الطريقة دي أفضل؟
✅ كود أنضف وأسهل قراءة
كل حاجة واضحة… مفيش Exceptions مستخبية.✅ تقليل الأخطاء المفاجئة
مفيش Crash بسبب Error مش معمول له Handling.✅ تحسين تجربة التطوير
هتشتغل أسرع وهتفهم الكود بسهولة.✅ قابلية توسع عالية
تقدر تضيف حالات جديدة زي: Loading - Empty بسهولة جدًا.مقارنة سريعة
| الطريقة | العيوب |
|---|---|
| try-catch | عشوائية، صعب تتبعها |
| Freezed + Result | منظمة، آمنة، واضحة |
نصائح احترافية
- استخدم Freezed لكل Responses المهمة
- متخلطش بين Exceptions وResult Pattern
- خليك consistent في المشروع كله
- اربطها مع Cubit أو Bloc عشان أفضل نتيجة
الخلاصة
لو عايز كود نظيف، آمن، وسهل الصيانة…ابعد عن try-catch العشوائية وابدأ استخدم: Freezed + Union Types
هتلاحظ فرق كبير في:
- جودة الكود 💯
- سرعة التطوير 🚀
- تقليل الأخطاء 🛡️
الكود النضيف مش رفاهية… ده استثمار في مستقبل مشروعك.