ErrorOr لـ C# (.NET): دليل شامل لمعالجة الأخطاء بدون استثناءات
في التطوير الحديث باستخدام C# (.NET)، تعتمد معالجة الأخطاء تقليديًا على آلية الاستثناءات (exceptions). لكن لهذا النهج عدة عيوب: فالاستثناءات تعطل تدفق التنفيذ، وتستهلك موارد إضافية على المكدس (stack)، والأهم من ذلك، أنها لا تخبر المطور بشكل صريح بأن الدالة قد تفشل. تقدم مكتبة ErrorOr بديلاً وظيفيًا (functional approach)، حيث يتم إرجاع نتيجة العملية ككائن خاص يمكن أن يحتوي إما على قيمة ناجحة أو قائمة بالأخطاء.
الفكرة الأساسية لـ ErrorOr هي جعل معالجة الأخطاء صريحة وآمنة من حيث النوع. بدلاً من رمي استثناء، تقوم الدالة بإرجاع كائن من النوع ErrorOr<TValue>. الكود المستدعي ملزم بالتحقق مما إذا كانت العملية قد نجحت قبل استخدام النتيجة. هذا يمنع العديد من الأخطاء البرمجية المرتبطة بالاستثناءات غير المعالجة، ويجعل الكود أكثر قابلية للتنبؤ وأسهل في الفهم.
المكتبة مستوحاة من لغات ذات نظام أنواع متقدم، مثل Rust (النوع Result<T, E>) وF# (النوع Result<'T, 'TError>). تعتبر ErrorOr مثالية لـ Clean Architecture و Domain-Driven Design (DDD) ومشاريع CQRS، حيث من المهم الفصل بوضوح بين السيناريوهات الناجحة والخاطئة. كما أنها تعمل بشكل ممتاز مع نمط "Railway Oriented Programming"، مما يسمح ببناء سلاسل من العمليات مع نقل الأخطاء تلقائيًا.
التثبيت
يتم تثبيت مكتبة ErrorOr في مشروع .NET عبر مدير الحزم NuGet. قم بتنفيذ أحد الأوامر التالية في الطرفية (Terminal) أو في وحدة تحكم مدير الحزم (Package Manager Console):
dotnet add package ErrorOr
أو، إذا كنت تستخدم Package Manager Console في Visual Studio:
Install-Package ErrorOr
بعد التثبيت، قم بتضمين مساحة الاسم (namespace) في ملف الكود الخاص بك:
using ErrorOr;
بداية سريعة: مثال عملي بسيط
لنكتب دالة بسيطة تقسم رقمًا على آخر. بدلاً من رمي استثناء عند القسمة على صفر، سنقوم بإرجاع ErrorOr<double>.
using ErrorOr;
public static class Calculator
{
public static ErrorOr<double> Divide(double dividend, double divisor)
{
if (divisor == 0)
{
// إرجاع خطأ إذا كان المقسوم عليه صفرًا
return Error.Validation("Calculator.DivisionByZero", "لا يمكن أن يكون المقسوم عليه صفرًا.");
}
// إرجاع نتيجة ناجحة
return dividend / divisor;
}
}
// الاستخدام
public class Program
{
public static void Main()
{
ErrorOr<double> result = Calculator.Divide(10, 2);
if (result.IsError)
{
Console.WriteLine($"فشلت العملية: {result.FirstError.Description}");
}
else
{
Console.WriteLine($"النتيجة: {result.Value}");
}
// مثال مع خطأ
ErrorOr<double> errorResult = Calculator.Divide(10, 0);
if (errorResult.IsError)
{
Console.WriteLine($"فشلت العملية: {errorResult.FirstError.Description}");
}
}
}
في هذا المثال، نرى العناصر الأساسية: إنشاء خطأ عبر Error.Validation()، إرجاع قيمة ناجحة (تحويل ضمني)، والتحقق من النتيجة عبر الخاصية IsError.
الطرق والدوال والكلاسات الأساسية
فيما يلي شرح تفصيلي للمكونات الرئيسية لمكتبة ErrorOr. لكل عنصر، تم توضيح التوقيع (signature) والوصف ومثال عملي للكود.
1. الكلاس ErrorOr<TValue>
التوقيع: public rea