トラック
/
Roc
Roc
/
演習
/
エラー処理
エラー処理

エラー処理

中級

説明

さまざまな種類のエラー処理とリソース管理を実装してください。

プログラミングで重要なのは、エラーが起きたときでも、エラーを適切に処理してリソースを閉じる方法です。

この演習では、さまざまなエラーを処理する必要があります。エラー処理はプログラミング言語によって大きく異なるため、何が必要なのかを正確に知るには、自分のトラックのテストを参照する必要があります。

実装

小さなWebサーバーを作り、さらに小さなユーザーデータベースに問い合わせます。簡単そうに思えますが、現実の世界では、多くのことがうまくいかないものです(しかもよくあります)。

  • 接続が安全でない可能性があります。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(KeyNotFound)ではなくErr(UserNotFound(user_id))を返すようにしてください。
  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"

注: HTTPSではなくHTTPを使った場合にエラーメッセージを表示する代わりに、WebサーバーがブラウザをHTTPSへリダイレクトすれば、ユーザーはエラーに気づきもしません。Rocではエラーが機械に優しい形なので、これを実装するのはとても簡単です。

GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Roc Exercism

エラー処理を始める準備はできましたか?

Exercismに登録すれば、126個の演習、そして本物の人間によるメンタリングとともに、Rocを学んでマスターできます。すべて無料です。