فرض کنید کاربر میخواهد سفارشی ثبت کند، اما موجودی کالا کافی نیست.
❌ این یک Exception نیست:
throw new OutOfStockException();
✅ این یک نتیجهی قابل انتظار از منطق کسبوکار است:
return Result.Failure(Errors.Product.OutOfStock);
چرا؟
🔹 ساختن Exception شامل ایجاد Stack Trace است که هزینهی CPU و حافظه دارد.
🔹 پرتاب و Catch کردن Exception مسیر اجرای برنامه را کندتر میکند.
🔹 درواقع Exception برای اتفاقات غیرمنتظره طراحی شده است، نه اعتبارسنجی قوانین کسبوکار.
قاعدهای که همیشه از آن استفاده میکنیم:
✅ Expected Error → "Result"
• موجودی کافی نیست.
• کاربر پیدا نشد.
• اعتبارسنجی ناموفق بود.
• سفارش قبلاً پرداخت شده است.
❌ Unexpected Error → "throw"
• قطع شدن Database
• خطای شبکه
• باگ برنامه
• شرایطی که هرگز نباید رخ دهند
به این ترتیب:
✔️ کد خواناتر میشود.
✔️ جریان اجرای برنامه شفافتر است.
✔️ از هزینهی غیرضروری Exceptionها جلوگیری میشود.
✔️ و Performance در سناریوهای پرتکرار بهتر خواهد بود.
پس Result برای کنترل جریان عادی برنامه است و Exception برای شرایط استثنایی.