實作各種錯誤處理與資源管理方式。
程式設計的一個重點,就是即使發生錯誤,也要懂得如何處理錯誤並關閉資源。
這個練習要求你處理各種錯誤。由於錯誤處理與程式語言息息相關,你需要參考你正在學習的語言的測試,才能知道確切的要求。
你正在打造一個迷你的網頁伺服器,用來查詢一個更迷你的使用者資料庫。聽起來很簡單,但在真實世界裡,很多事情都可能(而且經常真的會)出錯:
"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 函式可以用來解析各種整數:天數、秒數、使用者 ID 等等。如果錯誤訊息只寫 Could not convert string "0.5" to a positive integer,使用者可能沒有足夠的脈絡來解決問題。所以在這個練習裡,你的錯誤會改為攜帶一個有意義的標籤,以及它自己有用的酬載。例如,如果找不到使用者,錯誤會長得像 Err(UserNotFound(42))。
好,我們開始吧!以下是你需要做的事:
get_user,從 users「資料庫」(其實只是一個 Dict)回傳被請求的使用者。請確保在找不到使用者時,函式回傳 Err(UserNotFound(user_id)),而不是 Err(KeyNotFound)。parse_user_id,把 URL 的路徑(例如 "/users/123")轉換成正整數的使用者 ID(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>",解析出使用者 ID,載入該 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 的錯誤是方便機器處理的,這會非常容易實作。