カスタム例外の作成
Apex 組み込み例外を発生させることはできません。この例外はキャッチのみ可能です。ただし、カスタム例外の場合、メソッドでの発生とキャッチが可能です。カスタム例外では、詳細なエラーメッセージを指定したり、catch ブロックでカスタマイズしたエラー処理を行ったりできます。
例外は最上位クラスにできます。つまり、メンバー変数、メソッド、コンストラクタを持ち、インターフェースの実装などが可能です。
カスタム例外クラスを作成するには、組み込み Exception クラスを拡張して、「MyException」や「PurchaseException」のようにクラス名の最後が Exception で終わるように指定します。すべての例外クラスは、システム定義の基本クラス Exception を拡張するため、すべての共通例外メソッドを継承します。
Java クラスと同様に、ユーザ定義の例外型は継承ツリーを構成し、catch ブロックでこの継承ツリー内の任意のオブジェクトをキャッチできます。次に例を示します。
独自の例外オブジェクトは次のような形で作成し、発生させることができます。
- 引数のない例外
- エラーメッセージを指定する 1 つの string 型の引数を取る例外
- 1つの Exception 型の引数を取るもの。これは原因を特定でき、任意にスタック追跡できます。
- string 型のエラーメッセージと、任意のスタック追跡に表示される例外チェーンの両方を取る例外
例外と内部例外の再発生
catch ブロックで例外をキャッチしたら、キャッチした例外変数を再発生させることもできます。これは、メソッドが別のメソッドによってコールされていて、コール元のメソッドに例外の処理を委任する場合に役立ちます。キャッチした例外をカスタム例外の内部例外として再発生させ、メインメソッドにカスタム例外種別をキャッチさせることができます。
次の例では、内部例外として例外を再発生させる方法を示します。この例では、My1Exception と My2Exception の 2 つのカスタム例外を定義し、両方の情報を使用してスタック追跡を生成します。
上記のコードを実行した結果のスタック追跡は次のようになります。
15:52:21:073 EXCEPTION_THROWN [7]|My1Exception: First exception
15:52:21:077 EXCEPTION_THROWN [11]|My2Exception: Throw with inner exception
15:52:21:000 FATAL_ERROR AnonymousBlock: line 11, column 1
15:52:21:000 FATAL_ERROR Caused by
15:52:21:000 FATAL_ERROR AnonymousBlock: line 7, column 1
次のセクションの例では、getCause メソッドをコールし、内部例外を使用して例外を処理する方法を示します。
内部例外の例
カスタム例外クラスの作成方法と、例外オブジェクトの構築方法を確認したので、カスタム例外の便利さを示す例を作成して実行してみましょう。
- 開発者コンソールで、MerchandiseException という名前のクラスを作成し、次のコンテンツが含まれていることを確認します。
この例外クラスは、これから作成する 2 つ目のクラス内で使用します。最後の中括弧で例外クラスの本文を囲みます。例外クラスは空のままにしておき、既存のコードを使用します。このクラスは、組み込み Exception クラスから、getMessage など、すべてのコンストラクタと共通例外メソッドを継承するためです。
- 続いて、2 つ目のクラスを MerchandiseUtility という名前で作成します。
このクラスには、mainProcessing メソッドが含まれ、そのメソッドから insertMerchandise がコールされます。このコール先で、必須項目を指定せずに Merchandise が挿入されるため、例外が発生します。catch ブロックはこの例外をキャッチし、前に作成した新しい例外であるカスタムの MerchandiseException を発生させます。ここでは、2 つの引数 (エラーメッセージ、元の例外オブジェクト) を取る例外のコンストラクタをコールしています。なぜ元の例外を渡すのでしょうか。それは、最初のメソッド mainProcessing で MerchandiseException をキャッチした場合、この例外の本当の原因は MerchandiseException よりも前に発生した元の例外 (内部例外と呼ばれる) であるため、元の例外の情報が役に立つからです。
- 理解を深めるために、これらが実際にどう機能するのか見てみましょう。次のコードを実行します。
- デバッグログ出力を確認します。ログには、次のように表示されます。
18:12:34:928 USER_DEBUG [6]|DEBUG|Message: Merchandise item could not be inserted.
18:12:34:929 USER_DEBUG [7]|DEBUG|Cause: System.DmlException: Insert failed.First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Description, Price, Total Inventory]: [Description, Price, Total Inventory]
18:12:34:929 USER_DEBUG [8]|DEBUG|Line number: 22
18:12:34:930 USER_DEBUG [9]|DEBUG|Stack trace: Class.EmployeeUtilityClass.insertMerchandise: line 22, column 1
次の点に留意してください。- MerchandiseException の原因は DmlException です。必須項目がないことを示す DmlException メッセージも表示されます。
- スタック追跡は、2 つ目の例外が発生した場所である行 22 です。MerchandiseException の throw ステートメントに対応しています。