Tr

Try/Rescue در Elixir

1 تمرین

درباره‌ی Try/Rescue

از try .. rescue می‌توان برای گرفتن و ارزیابی خطاهایی که داخل یک بلوک ایجاد می‌شوند استفاده کرد.

برای مثال:

try do
  raise RuntimeError, "error"
rescue
  e in RuntimeError -> :error
end
  • خط ۱، بلوک با try اعلام می‌شود.
  • خط ۲، فراخوانی تابعی که ممکن است خطا تولید کند اینجا قرار می‌گیرد؛ در این مورد ما raise/1 را فراخوانی می‌کنیم.
  • خط ۴، در بخش rescue، روی اسم ماژول خطای ایجادشده تطبیق الگو می‌کنیم
    • در سمت چپ ->:
      • e با ساختار خطا تطبیق داده می‌شود.
      • in یک کلیدواژه است.
      • RuntimeError ماژولی است که تطبیق داده می‌شود، اما می‌توان روی هر ماژول خطایی تطبیق داد، یا با _ روی همه‌ی خطاها.
    • در سمت راست:
      • دستورهایی که در صورت تطبیق خطا اجرا می‌شوند.

ساختارهای خطا

خطاهایی (که گاهی «استثنا» هم نامیده می‌شوند) که به این روش نجات می‌دهید، ساختار هستند. ساختارهای خطای مختلف کلیدهای متفاوتی دارند. در بخش «استثناها» کتابخانه‌ی استاندارد می‌توانید فهرستی از همه‌ی خطاهای از پیش تعریف‌شده پیدا کنید.

# ArithmeticError caused by division by zero
%ArithmeticError{message: "bad argument in arithmetic expression"}

# Protocol.UndefinedError caused by passing `nil` to `Enum.count/1`
%Protocol.UndefinedError{description: "", protocol: Enumerable, value: nil}

نجات دادن خطاها در Elixir بسیار به‌ندرت انجام می‌شود. معمولاً خطای نجات‌یافته ثبت می‌شود یا به یک سرویس پایش خارجی فرستاده می‌شود و بعد دوباره ایجاد می‌شود. یعنی معمولاً جزئیات درونیِ ساختار خطای مشخص برایمان مهم نیست.

مفهوم استثناها توضیح می‌دهد که چطور ساختارهای خطای سفارشی تعریف کنیم.

از ضدالگوها بپرهیزید

  • از الگوهای برنامه‌نویسی‌ای که از خطاها برای کنترل جریان منطقی استفاده می‌کنند بپرهیزید. این یک ضدالگو در Elixir است.

    # Avoid using errors for control-flow.
    try do
      {:ok, value} = MyModule.janky_function()
      "All good! #{value}."
    rescue
      e in RuntimeError ->
        reason = e.message
        "Uh oh! #{reason}."
    end
    
    # Rather, use control-flow structures for control-flow.
    case MyModule.janky_function() do
      {:ok, value} -> "All good! #{value}."
      {:error, reason} -> "Uh oh! #{reason}."
    end
    

خطا ایجاد کنیم یا نه، مسئله این است

همان‌طور که در راهنمای شروع به کار Elixir نوشته شده است:

تصمیم این‌که خطایی هنگام [انجام یک کار] استثنایی هست یا نه بر عهده‌ی برنامه‌ی شماست. به همین دلیل Elixir استثناها را بر [...] توابع تحمیل نمی‌کند. در عوض، انتخاب بهترین شیوه‌ی ادامه دادن را به عهده‌ی توسعه‌دهنده می‌گذارد.

ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

Try/Rescue را یاد بگیرید