انواع مختلفی از مدیریت خطا و منابع را پیادهسازی کنید.
یکی از نکات مهم در برنامهنویسی این است که چگونه خطاها را مدیریت کنیم و منابع را حتی وقتی خطا رخ میدهد ببندیم.
این تمرین از شما میخواهد که خطاهای مختلفی را مدیریت کنید. از آنجا که مدیریت خطا تا حد زیادی به زبان برنامهنویسی بستگی دارد، باید به تستهای مربوط به track خود مراجعه کنید تا ببینید دقیقاً چه چیزی لازم است.
شما در حال ساختن یک وبسرور کوچک هستید که از یک پایگاهدادهی کاربران حتی کوچکتر پرسوجو میکند. ساده به نظر میرسد، اما در دنیای واقعی ممکن است مشکلات زیادی پیش بیاید (و اغلب هم پیش میآید):
"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)) خواهد بود.
خب، بیایید شروع کنیم! کارهایی که باید انجام دهید اینهاست:
get_user را طوری پیادهسازی کنید که کاربر درخواستشده را از «پایگاهدادهی» users برگرداند (که در واقع فقط یک Dict است). مطمئن شوید که اگر کاربر پیدا نشد، تابع بهجای Err(KeyNotFound) مقدار Err(UserNotFound(user_id)) را برمیگرداند.parse_user_id را پیادهسازی کنید تا مسیر URL (مثل "/users/123") را به یک شناسهی کاربر عدد صحیح مثبت (123) تبدیل کند. در صورت خطا، Err(InvalidUserId(user_id_str)) را برگردانید.getPage را پیادهسازی کنید:
"https://example.com/" باشد، Ok("Home page") را برگردانید"https://example.com/users/" باشد، Ok("Users page") را برگردانید"https://example.com/users/<user_id>" باشد، شناسهی کاربر را تجزیه کنید، کاربری با آن شناسه را بارگذاری کنید و Ok("<user name>'s page") را برگردانید"https://" نباشد، Err(InsecureConnection(url)) را برگردانید"example.com" نباشد، Err(InvalidDomain(url)) را برگردانید/ یا /users/ یا /users/<user id> نباشد، Err(PageNotFound(path)) را برگردانیدErr(InvalidUserId(user_id_str)) را برگردانیدErr(UserNotFound(user_id)) را برگردانید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 ماشینپسند هستند، پیادهسازی این کار بسیار ساده خواهد بود.