۵  روش کاربردی برای مدیریت خطا‌‌ها در C#

تهیه‌کننده مقاله : حمید نوعهدی

5 دقیقه زمان مطالعه
1401/07/26
2 نظر

بهترین راه برای جلوگیری از بروز اشکالات و bug ها در نرم‌افزا یا اپلیکیشن‌ها این است که از  خطا‌هایی که ممکن است در کد شما رخ دهد، جلوگیری کنید. اگر بتوانید از آن‌ها جلوگیری کنید، مجبور نخواهید شد، آن‌ها را دوباره بررسی کنید و در صورت وقوع آن‌ها را مدیریت کنید. به نظر شما این موضوع درست است؟

در حالی که این موضوع از نظر تئوری خوب به نظر می‌رسد، همیشه نمی‌توان به طور کامل از بروز خطاها و مشکلات در نرم افزار جلوگیری کرد. در غیر این صورت اصلا برنامه یا اپلیکیشنی نداشتیم!

 هنگامی که یک خطا در برنامه رخ می‌دهد و برنامه شما نمی‌تواند به خودی خود درست شود، نحوه رسیدگی به خطا به میزان اطلاعاتی که خطا درمورد علت و محل بروز آن ارائه می‌دهد، بستگی دارد.

به همین دلیل در این مقاله ۵ روش ساده و مفید برای مدیریت خطاها در C# را توضیح می‌دهیم.

درک کلی از error handling

قبل از هر چیز لازم است بدانیم مدیریت خطا یا error handling به چه معناست. این اصطلاح به واکنش و مکانیسم‌های بازیابی نرم‌افزار در صورت بروز خطا اشاره می‌کند. به عبارت دیگر این کار فرآیندی است که شامل پیش‌بینی دقیق، شناسایی و رفع خطاها در برنامه‌ها است.

اجرای منظم یک برنامه از طریق مدیریت خطا آسان‌تر است. وقتی صحبت از رویکردهای  خطا handling می‌شود، بسیاری از برنامه‌ها با مشکلات معماری نرم‌افزار مواجه می‌شوند.

به خاطر بسپارید که بروز خطا در برنامه نشانه خوبی است.

همیشه stack ها را نگه دارید

استفاده ازThrow e ;   راه خوبی برای throw a caught نیست چون C#  به ما این امکان را می‌دهد که به سادگی با Throw، یک  exception را در بلوک catch قرار دهیم.

به این ترتیب ما stack را ردیابی می‌کنیم و دید بسیار بهتری از exception  داریم.

روش نادرست:

try
{
    FunctionThatMightThrow();
}
catch (Exception ex)
{
    logger.LogInfo(ex);
    throw ex;
}

روش صحیح:

try
{
    FunctionThatMightThrow();
}
catch (Exception خطا)
{
    logger.LogInfo(خطا);
    throw;
}

گنجاندن اطلاعات در exception کار خوبی است چون به رفع مشکل‌ها و  debug کمک می‌کند.

از throw exاستفاده نکنید

در نگاه اول هر توسعه‌دهنده‌ای می‌تواند باور داشته باشد که throw ex بهترین راه برای بازگرداندن یک exception پس از گرفتن آن است. بله این یک راه ساده برای انجام این کار است، اما راه درستی نیست. این گزینه خوب نیست زیرا شما رد stack  را از دست خواهید داد.

روش نادرست:

try
{
    // Do something..
}
catch (Exception ex)
{
    // Any action something like roll-back or logging etc.
    throw ex;
}

روش صحیح:

try
{
    // Do something..
}
catch (Exception ex)
{
    // Any action something like roll-back or logging etc.
    throw;
}

در مثال بالا می‌توانید ببینید که به سادگی از throw استفاده شده است. به این ترتیب stack  اصلی حفظ می‌شود. در غیر این صورت با throw ex با یک خط کد که این دستور را فراخوانی کرده است، بازنویسی می‌شود.

از استفاده if condition خودداری کنید

در صورت نیاز به انجام catch blocks های مختلف برای مدیریت exception باید اقدامات  مختلفی بسته به نوع exception انجام دهید. یک روش نامناسب این است که از دستور if conditional  استفاده کنید.

روش نادرست:

try
{
    // Do something..
}
catch (Exception ex)
{
    if (ex is TaskSchedulerException)
    {
        // Take action
    }
    else if (ex is TaskCanceledException)
    {
        // Take action
    }
}

روش صحیح:

try
{
    // Do something..
}
catch (TaskCanceledException ex)
{
    // Take action 
}
catch (TaskSchedulerException ex)
{
    // Take action
}

حتی اگر در حال ایجاد بلوک‌های catch متعدد هستیم، همیشه پیشنهاد می‌شود که یک block  catch ایجاد کنیم که شامل آرگومان Exception به عنوان block catch نهایی باشد که آن را به عنوان یک catch block کمکی فراهم می‌کند.

همیشه خطاهای کشف شده را تجزیه و تحلیل کنید

اگریک خطا را تشخیص دادید، فایده ای ندارد که آن را نادیده گرفته و رها کنید زیرا فرصتی برای رفع آن یا انجام کار برای آن نخواهید داشت.

روش مناسب برای برطرف کردن این موضوع این است که اگر می دانید ممکن است خطا رخ دهد، کد را در یک try/catch قرار دهید.

روش نادرست:

try
{
    FunctionThatMightThrow();
}
catch (Exception ex)
{
    // silent exception
}

روش صحیح:

try
{
    FunctionThatMightThrow();
}
catch (Exception خطا)
{
    NotifyUserOfخطا(خطا);    // Another option
    ReportخطاToService(خطا);
}

همانطور که می‌بینیم، نادیده  گرفتن خطا راه حل خوبی برای برطرف کردن آن نیست چون ممکن است در بین تمام موارد چاپ شده در console گم شود. با قرار دادن آن در یک try/catchمی‌توانیم در ادامه و در صورت بروز خطا برنامه‌ریزی داشته یا یک مسیر کد برای نحوه مدیریت آن داشته باشیم

منبع مقاله:

https://medium.com/bytehide/5-good-practices-for-error-handling-in-c-9faee15404fa