مسیرها
/
Roc
Roc
/
تمرین‌ها
/
مدیریت خطا
مدیریت خطا

مدیریت خطا

متوسط

دستورالعمل‌ها

انواع مختلفی از مدیریت خطا و منابع را پیاده‌سازی کنید.

یکی از نکات مهم در برنامه‌نویسی این است که چگونه خطاها را مدیریت کنیم و منابع را حتی وقتی خطا رخ می‌دهد ببندیم.

این تمرین از شما می‌خواهد که خطاهای مختلفی را مدیریت کنید. از آنجا که مدیریت خطا تا حد زیادی به زبان برنامه‌نویسی بستگی دارد، باید به تست‌های مربوط به track خود مراجعه کنید تا ببینید دقیقاً چه چیزی لازم است.

پیاده‌سازی

شما در حال ساختن یک وب‌سرور کوچک هستید که از یک پایگاه‌داده‌ی کاربران حتی کوچک‌تر پرس‌وجو می‌کند. ساده به نظر می‌رسد، اما در دنیای واقعی ممکن است مشکلات زیادی پیش بیاید (و اغلب هم پیش می‌آید):

  • اتصال ممکن است ناامن باشد: URL باید با "https://" شروع شود
  • دامنه ممکن است نامعتبر باشد: در این تمرین باید "example.com" باشد
  • صفحه ممکن است پیدا نشود: فقط "https://example.com/"، "https://example.com/users/" و "https://example.com/users/<user_id>" مجاز هستند
  • user_id ممکن است یک عدد صحیح مثبت نباشد
  • ممکن است هیچ کاربری با این user_id در پایگاه‌داده وجود نداشته باشد

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

خوشبختانه Roc به شما اجازه می‌دهد که محموله (یعنی داده) را داخل برچسب Err خودتان حمل کنید. وسوسه‌انگیز است که مستقیم یک پیام خطا حمل کنید (مثلاً Err("User #42 was not found")) و این ممکن است در برخی موارد ساده اشکالی نداشته باشد، اما چند محدودیت دارد:

  • ممکن است داخل تابعی که خطا را تشخیص می‌دهد، زمینه‌ی کافی نداشته باشید تا پیام خطایی به‌اندازه‌ی کافی مفید تولید کنید.
    • برای مثال، از تابع Str.to_u64 می‌توان برای تجزیه‌ی انواع اعداد صحیح استفاده کرد: روزها، ثانیه‌ها، شناسه‌های کاربر و بیشتر. اگر پیام خطا فقط بگوید Could not convert string "0.5" to a positive integer، ممکن است کاربر زمینه‌ی کافی برای حل مشکل نداشته باشد.
  • در بسیاری از موارد، ممکن است کد مدیریت خطای شما لازم باشد با بعضی خطاها متفاوت از بقیه رفتار کند. اما اگر خطاها فقط محموله‌ی رشته‌ای حمل کنند، کد مدیریت خطای شما باید آن رشته را تجزیه کند تا بفهمد چه مشکلی رخ داده است: این کار ناکارآمد است و اگر پیام خطا روزی دستکاری شود، به‌راحتی می‌شکند.
  • اگر وب‌سایتتان چندزبانه باشد، باید پیام خطا را به زبان کاربر ترجمه کنید. انجام این کار زمانی بسیار ساده‌تر است که محموله‌ی خطا داده‌های ماشین‌پسند باشد، نه یک رشته‌ی انگلیسی.

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

خب، بیایید شروع کنیم! کارهایی که باید انجام دهید این‌هاست:

  1. تابع get_user را طوری پیاده‌سازی کنید که کاربر درخواست‌شده را از «پایگاه‌داده‌ی» users برگرداند (که در واقع فقط یک Dict است). مطمئن شوید که اگر کاربر پیدا نشد، تابع به‌جای Err(KeyNotFound) مقدار Err(UserNotFound(user_id)) را برمی‌گرداند.
  2. تابع parse_user_id را پیاده‌سازی کنید تا مسیر URL (مثل "/users/123") را به یک شناسه‌ی کاربر عدد صحیح مثبت (123) تبدیل کند. در صورت خطا، Err(InvalidUserId(user_id_str)) را برگردانید.
  3. تابع getPage را پیاده‌سازی کنید:
    • اگر URL برابر "https://example.com/" باشد، Ok("Home page") را برگردانید
    • اگر URL برابر "https://example.com/users/" باشد، Ok("Users page") را برگردانید
    • اگر URL برابر "https://example.com/users/<user_id>" باشد، شناسه‌ی کاربر را تجزیه کنید، کاربری با آن شناسه را بارگذاری کنید و Ok("<user name>'s page") را برگردانید
    • اگر پیشوند URL برابر "https://" نباشد، Err(InsecureConnection(url)) را برگردانید
    • اگر دامنه‌ی URL برابر "example.com" نباشد، Err(InvalidDomain(url)) را برگردانید
    • اگر مسیر / یا /users/ یا /users/<user id> نباشد، Err(PageNotFound(path)) را برگردانید
    • اگر شناسه‌ی کاربر یک عدد صحیح مثبت نباشد، Err(InvalidUserId(user_id_str)) را برگردانید
    • اگر کاربر وجود نداشته باشد، Err(UserNotFound(user_id)) را برگردانید
  4. تابع error_essage را پیاده‌سازی کنید تا خطاهای قبلی را به پیام‌های خطای ترجمه‌شده تبدیل کند. این تابع باید حداقل انگلیسی را پشتیبانی کند، اما تشویق می‌شوید که زبان دیگری را هم امتحان کنید. پیام‌های خطای انگلیسی باید این‌گونه باشند:
  • "Insecure connection (non HTTPS): http://example.com/users/789"
  • "Invalid domain name: https://google.com/wrong"
  • "Page not found: /oops"
  • "User ID is not a positive integer: abc"
  • "User #42 was not found"

نکته: به‌جای اینکه وقتی کاربر از HTTP به‌جای HTTPS استفاده می‌کند پیام خطایی به او نشان دهید، وب‌سرور شما می‌تواند مرورگر او را به HTTPS هدایت کند و کاربر حتی متوجه خطا هم نمی‌شود. چون خطاها در Roc ماشین‌پسند هستند، پیاده‌سازی این کار بسیار ساده خواهد بود.

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

آماده‌اید مدیریت خطا را شروع کنید؟

در Exercism ثبت‌نام کنید تا Roc را همراه با 126 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.