-
Notifications
You must be signed in to change notification settings - Fork 17
ErrorHandling
lriki edited this page Jun 28, 2022
·
1 revision
API(関数)の使い方がそもそも間違っている問題です。
次のようなケースが代表例です。
- APIに不正な引数を渡す (nullアクセスや範囲外アクセス)
- オブジェクトの状態によって不正な操作を行った (オブジェクトを構築するためのデータのロード中に、オブジェクトにアクセスしてしまった)
- 未実装の機能を呼び出した。
Lumino はこの状態を、バグか仕様かに関わらず、アプリケーションがプログラマの想定していなかった状況に陥っている状態(無理に復帰させても、不正なデータがDBに記録されたり、脆弱性の原因となったりする可能性がある)と考えます。 これを検出した場合、Lumino はアサーションハンドラを呼び出した後、ログを記録してアプリケーションをクラッシュさせます。
アプリケーションのユーザーの誤操作が原因の問題です。
次のようなケースが代表例です。
- テキストボックスに不正な文字を入力した。
- インターネットに接続していない状態でファイルをダウンロードしようとした。
- アプリケーションが開こうとしたファイルを、間違えて消してしまった。
このような問題が発生しうる関数は、戻り値が Result 型となっています。 簡単に言うと処理の成否を表す bool 型のようなもので、対策を講じるべき回復可能なエラーの存在をプログラマに対して明確に示すためのものです。
RustのResult に着想を得た機能です。 std::optional のように使用できますが、失敗時のエラー情報の保持や、異なる型のエラーを呼び出し元関数に返すBox機能があります。
典型的な使い方は次のようになります。
Result loadSettings(const Char* filePath) {
if (!filePath) return err();
ln::IOResult<ln::String> result = ln::FileSystem::readAllText(filePath);
if (result) {
// 読み込み成功
ln::String text = *result;
std::cout << text;
}
else {
// 読み込み失敗
return result;
}
return ok();
}// 型名が冗長になりやすいため、基本的には auto を使って受け取ったほうが簡単です。
auto result = ln::FileSystem::readAllText(filePath);
if (!result) return result;
// std::optional と同じく * や -> で値にアクセスできますが、より明示的に値の取得を示したい場合 unwrap() も同様に使用できます。
// いずれも、失敗時に呼び出すとロジックエラーとしてクラッシュが発生します。
auto text1 = result.unwrap();