學習軌道
/
Roc
Roc
/
練習
/
錯誤處理
錯誤處理

錯誤處理

中等

說明

實作各種錯誤處理與資源管理方式。

程式設計的一個重點,就是即使發生錯誤,也要懂得如何處理錯誤並關閉資源。

這個練習要求你處理各種錯誤。由於錯誤處理與程式語言息息相關,你需要參考你正在學習的語言的測試,才能知道確切的要求。

實作

你正在打造一個迷你的網頁伺服器,用來查詢一個更迷你的使用者資料庫。聽起來很簡單,但在真實世界裡,很多事情都可能(而且經常真的會)出錯:

  • 連線可能不安全: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 函式可以用來解析各種整數:天數、秒數、使用者 ID 等等。如果錯誤訊息只寫 Could not convert string "0.5" to a positive integer,使用者可能沒有足夠的脈絡來解決問題。
  • 在許多情況下,你的錯誤處理程式碼可能需要以不同的方式處理某些錯誤。但如果錯誤只攜帶字串酬載,你的錯誤處理程式碼就得解析那個字串,才知道發生了什麼問題:這既沒有效率,只要錯誤訊息稍微調整過就很容易壞掉。
  • 如果你的網站支援多種語言,你會需要把錯誤訊息翻譯成使用者所使用的語言。如果錯誤酬載是方便機器處理的資料,而不是英文字串,做起來會容易得多。

所以在這個練習裡,你的錯誤會改為攜帶一個有意義的標籤,以及它自己有用的酬載。例如,如果找不到使用者,錯誤會長得像 Err(UserNotFound(42))。

好,我們開始吧!以下是你需要做的事:

  1. 實作 get_user,從 users「資料庫」(其實只是一個 Dict)回傳被請求的使用者。請確保在找不到使用者時,函式回傳 Err(UserNotFound(user_id)),而不是 Err(KeyNotFound)。
  2. 實作 parse_user_id,把 URL 的路徑(例如 "/users/123")轉換成正整數的使用者 ID(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>",解析出使用者 ID,載入該 ID 對應的使用者,並回傳 Ok("<user name>'s page")
    • 如果 URL 的前綴不是 "https://",回傳 Err(InsecureConnection(url))
    • 如果 URL 的網域名稱不是 "example.com",回傳 Err(InvalidDomain(url))
    • 如果路徑不是 / 或 /users/ 或 /users/<user id>,回傳 Err(PageNotFound(path))
    • 如果使用者 ID 不是正整數,回傳 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,透過 126 個練習 和真人引導來學習並精通 Roc,全部免費。