この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

カスタム例外の作成

組み込み Apex 例外は意図的に発生させることはできず、キャッチすることしかできません。そのため、例外をメソッドで発生させるにはカスタム例外を作成します。カスタム例外を使用すると、詳細なエラーメッセージを指定したり、catch ブロックでカスタマイズしたエラー処理を行ったりすることもできます。

カスタム例外クラスを作成するには、組み込み Exception クラスを拡張して、クラス名の最後が Exception で終わるように指定します。クラス宣言の後に、次のように extends Exception を付加します。
1public class MyException extends Exception {}

独自の例外オブジェクトは次のような形で作成し、発生させることができます。

次のような例外を作成できます。
  • 引数のない例外
    1new MyException();
  • エラーメッセージを指定する 1 つの string 型の引数を取る例外
    1new MyException('This is bad');
  • 1つの Exception 型の引数を取るもの。これは原因を特定でき、任意にスタック追跡できます
    1new MyException(e);
  • string 型のエラーメッセージと、任意のスタック追跡に表示される例外チェーンの両方を取る例外
    1new MyException('This is bad', e);

例外クラスの作成方法と、例外オブジェクトの構築方法を学習したので、カスタム例外の便利さを示す例を作成して実行してみましょう。

  1. 開発者コンソールで、MerchandiseException という名前のクラスを作成し、次のコードを追加します。
    1public class MerchandiseException extends Exception {}

    この例外クラスは、これから作成する 2 つ目のクラス内で使用します。最後の中括弧で例外クラスの本文を囲みます。例外クラスは空のままにしておき、既存のコードを使用します。このクラスは、組み込み Exception クラスから、getMessage など、すべてのコンストラクタと共通例外メソッドを継承するためです。

  2. 続いて、2 つ目のクラスを MerchandiseUtility という名前で作成します。
    1public class MerchandiseUtility {
    2    public static void mainProcessing() {
    3        try {
    4            insertMerchandise();
    5        } catch(MerchandiseException me) {
    6            System.debug('Message: ' + me.getMessage());    
    7            System.debug('Cause: ' + me.getCause());    
    8            System.debug('Line number: ' + me.getLineNumber());    
    9            System.debug('Stack trace: ' + me.getStackTraceString());    
    10        }
    11    }
    12    
    13    public static void insertMerchandise() {
    14        try {
    15            // Insert merchandise without required fields
    16            Merchandise__c m = new Merchandise__c();
    17            insert m;
    18        } catch(DmlException e) {
    19            // Something happened that prevents the insertion
    20            // of Employee custom objects, so throw a more
    21            // specific exception.
    22            throw new MerchandiseException(
    23                'Merchandise item could not be inserted.', e);
    24        }
    25    }
    26}

    このクラスには、mainProcessing メソッドが含まれ、そのメソッドから insertMerchandise がコールされます。このコール先で、必須項目を指定せずに Merchandise が挿入されるため、例外が発生します。catch ブロックはこの例外をキャッチし、前に作成した新しい例外であるカスタムの MerchandiseException を発生させます。ここでは、2 つの引数 (エラーメッセージ、元の例外オブジェクト) を取る例外のコンストラクタをコールしています。なぜ元の例外を渡すのでしょうか。それは、最初のメソッド mainProcessing で MerchandiseException をキャッチした場合、この例外の本当の原因は MerchandiseException よりも前に発生した元の例外 (内部例外と呼ばれる) であるため、元の例外の情報が役に立つからです。

  3. 理解を深めるために、これらが実際にどう機能するのか見てみましょう。次のコードを実行します。
    1MerchandiseUtility.mainProcessing();
  4. デバッグログ出力を確認します。ログには、次のように表示されます。

    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 ステートメントに対応しています。
      1throw new MerchandiseException('Merchandise item could not be inserted.', e);