1. ホーム
  2. php

カスタム例外メッセージ。ベストプラクティス

2023-11-24 01:31:17

質問

例外メッセージを作成する際に、デバッグに役立つ情報を強制するためにどの程度の努力をすべきか、あるいは、ユーザーが正しい情報を提供することを信じるべきか、あるいは、情報収集を例外ハンドラに委ねるべきか、疑問に思っています。

私は、多くの人々が彼らの例外をこのように行うのを見ます。

throw new RuntimeException('MyObject is not an array')

または、デフォルトの例外を、例外の名前を変えるだけで、たいしたことはしないカスタム例外で拡張することもできます。

throw new WrongTypeException('MyObject is not an array')

しかし、これはあまりデバッグ情報を提供しませんし、エラーメッセージの書式を強制するものではありません。そのため、まったく同じエラーが2つの異なるエラーメッセージを生成してしまう可能性があります...例えば "Database connection failed" vs "Could not connect to db"

確かに、もしそれが一番上に泡立つなら、それはスタックトレースを表示するでしょう、それは便利ですが、それは常に私が知る必要があるすべてを教えてくれるわけではありません。

私は以下のコードのようなものについて考え始めています。 を必要とする。 を要求し、正しいエラーメッセージを生成するために必要な引数を例外のスローワーに供給します。これはその中で行くべき方法かもしれないと考えています。

  • 最低レベルの有用な情報が提供されなければならない
  • ある程度一貫したエラーメッセージを生成する
  • 例外メッセージのテンプレートはすべて1つの場所(例外クラス)にあるため、メッセージの更新が容易...

しかし、使いにくい(例外の定義を調べなければならない)という欠点もあり、他のプログラマが提供された例外を使うことを躊躇してしまうかもしれません...。

一貫性のある、柔軟な例外メッセージフレームワークのためのベストプラクティスです。

/**
* @package MyExceptions
* MyWrongTypeException occurs when an object or 
* datastructure is of the incorrect datatype.
* Program defensively!
* @param $objectName string name of object, eg "\$myObject"
* @param $object object object of the wrong type
* @param $expect string expected type of object eg 'integer'
* @param $message any additional human readable info.
* @param $code error code.
* @return Informative exception error message.
* @author secoif
*/
class MyWrongTypeException extends RuntimeException {
    public function __construct($objectName, $object, $expected, $message = '', $code = 0) {
        $receivedType = gettype($object) 
        $message = "Wrong Type: $objectName. Expected $expected, received $receivedType";
        debug_dump($message, $object);
        return parent::__construct($message, $code);
    }
}

....

/**
 * If we are in debug mode, append the var_dump of $object to $message
 */
function debug_dump(&$message, &$object) {
     if (App::get_mode() == 'debug') {
         ob_start();
         var_dump($object);
         $message = $message . "Debug Info: " . ob_get_clean();
    }
}

のように使われる。

// Hypothetical, supposed to return an array of user objects
$users = get_users(); // but instead returns the string 'bad'
// Ideally the $users model object would provide a validate() but for the sake
// of the example
if (is_array($users)) {
  throw new MyWrongTypeException('$users', $users, 'array')
  // returns 
  //"Wrong Type: $users. Expected array, received string
}

で、html出力に適したものにするために、カスタム例外ハンドラでnl2brのようなことを行うかもしれません。

読書中。 http://msdn.microsoft.com/en-us/library/cc511859.aspx#

といった記載はないので、もしかしたらダメなのかもしれませんが...。

どのように解決するのですか?

のアドバイスを強くお勧めします。 Krzysztofのブログ にあるアドバイスを強くお勧めします。また、あなたのケースでは、彼が Usage Errors と呼んでいるものに対処しようとしているようなので、注意してください。

この場合、必要なのはそれを示す新しい型ではなく、それを引き起こしたものについてのより良いエラーメッセージです。そのようなものとして、どちらかのヘルパー関数があります。

  1. 例外に配置するテキスト文字列を生成する。
  2. 例外とメッセージ全体を生成します。

は必要なものです。

アプローチ1はより明確ですが、少し冗長な使い方につながるかもしれません。2はその逆で、より明確でないためにより短い構文を取引します。

関数は非常に安全でなければならず(それらは決して、無関係な例外を自ら引き起こしてはなりません)、特定の妥当な使用においてオプションであるデータの提供を強制してはならないことに注意してください。

これらのアプローチのいずれかを使用することにより、必要であれば、エラーメッセージを後で国際化することが容易になります。

スタックトレースは最低でも関数と、おそらくは行番号を与えます。したがって、そこから容易に判明しない情報を提供することに焦点を当てるべきです。