via pixabay.com
はじめに
Salesforceのエンジニアであれば一度は使うであろうフローですが、エラーを考慮した設計についてじっくり考えてみたことはありますでしょうか。
画面からの操作で意外と簡単に作れてしまう一方、エラーに関してはノータッチでした・・みたいなことがなきにしもあらずではと思います。
今回はフローでできる例外処理に関して紹介しますので、これを機にぜひ一緒に考えてみましょう!
※前提として、この記事における「エラー」と「例外」は同様の概念とします。
画面からの操作で意外と簡単に作れてしまう一方、エラーに関してはノータッチでした・・みたいなことがなきにしもあらずではと思います。
今回はフローでできる例外処理に関して紹介しますので、これを機にぜひ一緒に考えてみましょう!
※前提として、この記事における「エラー」と「例外」は同様の概念とします。
例外処理を行うメリット
例外処理とはエラーが起きた時に行う処理のことです。
例外処理を行うメリットとしては、エラーが起きた時にどんな処理を行うかを事前に定義できることで、それによりエラー発生時の調査がしやすくなったりデータの整合性を保ちやすくなったりすることだといえるでしょう。
例えば調査用に対象レコードの詳細情報をメールで送ったり、処理をロールバックすることで不要なデータの登録を防いだり、ユーザーにエラー画面を表示するなど、状況に合わせた対応を取ることが可能です。
例外処理を行うメリットとしては、エラーが起きた時にどんな処理を行うかを事前に定義できることで、それによりエラー発生時の調査がしやすくなったりデータの整合性を保ちやすくなったりすることだといえるでしょう。
例えば調査用に対象レコードの詳細情報をメールで送ったり、処理をロールバックすることで不要なデータの登録を防いだり、ユーザーにエラー画面を表示するなど、状況に合わせた対応を取ることが可能です。
エラーが発生するパターン
フローでエラーが発生するパターンはいろいろあるかと思いますが、今回は以下を想定します。
・レコード取得やレコード操作に失敗した場合
・特定の条件に合致した場合
・不正な値を入力した場合
それぞれでどのようなフローの要素を使って例外処理を行うかを一緒に考えてみましょう。
・レコード取得やレコード操作に失敗した場合
・特定の条件に合致した場合
・不正な値を入力した場合
それぞれでどのようなフローの要素を使って例外処理を行うかを一緒に考えてみましょう。
レコード取得やレコード操作に失敗した場合
レコードの取得や操作(作成、更新、削除)に失敗した際に利用できる要素として、以下があります。
■障害パス
フローの例外処理といえばコレというくらい最初に思いつく方が多いものかと思いますが、レコードの取得や操作に失敗した際に、その後の処理を定義できる要素になります。
例えばレコードの保存に失敗したら詳細情報のメールを送信する、エラー用のカスタムオブジェクトにレコードを作成する、画面フローであればエラー画面を表示するなどがあります。
こちらはレコードの取得や操作時以外に、メール通知やApex呼び出し等の「アクション」要素でも利用が可能です。
また、障害パスに入った時には必ず障害発生をお知らせするエラーメールが送信されます。
送信先は「フローを最後に変更したユーザー」または「Apex例外メール受信者」で、以下にて設定が可能です。
・設定>プロセスの自動化>プロセスまたはフローのエラーメールの送信先
■障害パス
フローの例外処理といえばコレというくらい最初に思いつく方が多いものかと思いますが、レコードの取得や操作に失敗した際に、その後の処理を定義できる要素になります。
例えばレコードの保存に失敗したら詳細情報のメールを送信する、エラー用のカスタムオブジェクトにレコードを作成する、画面フローであればエラー画面を表示するなどがあります。
こちらはレコードの取得や操作時以外に、メール通知やApex呼び出し等の「アクション」要素でも利用が可能です。
また、障害パスに入った時には必ず障害発生をお知らせするエラーメールが送信されます。
送信先は「フローを最後に変更したユーザー」または「Apex例外メール受信者」で、以下にて設定が可能です。
・設定>プロセスの自動化>プロセスまたはフローのエラーメールの送信先
■ロールバックレコード
こちらはトランザクション内で待機中の全レコードのレコード操作をキャンセルする要素で、
現状は画面フローの障害パスでのみ利用可能となっております。
例として以下の画面フローを使います。
この画面フローでは2つのレコード操作が1トランザクション内に存在しており、①のレコード作成要素の成功後、②のレコード作成要素で失敗して障害パスに入り「ロールバックレコード」要素が実行されたとします。
この場合、①と②はどちらも同一のトランザクションになるため、どちらのレコード作成もキャンセルされます。
こちらはトランザクション内で待機中の全レコードのレコード操作をキャンセルする要素で、
現状は画面フローの障害パスでのみ利用可能となっております。
例として以下の画面フローを使います。
この画面フローでは2つのレコード操作が1トランザクション内に存在しており、①のレコード作成要素の成功後、②のレコード作成要素で失敗して障害パスに入り「ロールバックレコード」要素が実行されたとします。
この場合、①と②はどちらも同一のトランザクションになるため、どちらのレコード作成もキャンセルされます。
「ロールバックレコード」要素を使わない場合、②で障害パスに入ったとしても①の待機中のレコードはトランザクション終了時に保存されていたため作成されてしまいます。
2つのレコードの作成が目的のフローだとすると①のレコードの作成は不要でしょう。
「ロールバックレコード」要素を利用することで、不要なレコードの作成を防ぐことが可能となります。
※障害パスを使わない場合はフロー全体が失敗します。
注意点として、ロールバックはトランザクション単位になるため複数のレコード操作がトランザクションを分けて存在する場合は、それぞれロールバックを設定する必要があります。
例えば①レコードA作成→②画面→③レコードB作成の場合、②の画面でトランザクションが分かれるため、③のレコードの作成で失敗したとしても①のレコードは作成されてしまいます。
その場合は、それぞれ障害パスと必要に応じてロールバックレコードを設定しましょう。
「ロールバックレコード」要素に関するHelp記事はこちらをご参照ください。
2つのレコードの作成が目的のフローだとすると①のレコードの作成は不要でしょう。
「ロールバックレコード」要素を利用することで、不要なレコードの作成を防ぐことが可能となります。
※障害パスを使わない場合はフロー全体が失敗します。
注意点として、ロールバックはトランザクション単位になるため複数のレコード操作がトランザクションを分けて存在する場合は、それぞれロールバックを設定する必要があります。
例えば①レコードA作成→②画面→③レコードB作成の場合、②の画面でトランザクションが分かれるため、③のレコードの作成で失敗したとしても①のレコードは作成されてしまいます。
その場合は、それぞれ障害パスと必要に応じてロールバックレコードを設定しましょう。
「ロールバックレコード」要素に関するHelp記事はこちらをご参照ください。
特定の条件に合致した場合
レコードが条件に合致した場合に、レコードを保存する前にエラーとして処理したいということがあると思います。
こちらで利用できる要素としては以下があります。
■条件分岐
「条件分岐」要素を利用して、エラー対象のレコードかどうかの判定を行います。
エラー対象と判定された場合は後続の処理を実行しないように通常と処理を分けて、メール通知や以下に記載の要素を利用してユーザーにエラーをお知らせするなどの対応を行います。
こちらで利用できる要素としては以下があります。
■条件分岐
「条件分岐」要素を利用して、エラー対象のレコードかどうかの判定を行います。
エラー対象と判定された場合は後続の処理を実行しないように通常と処理を分けて、メール通知や以下に記載の要素を利用してユーザーにエラーをお知らせするなどの対応を行います。
■カスタムエラーメッセージ
画面上にエラーメッセージを表示する要素で、レコードトリガーフローでのみ利用可能となっております。
入力規則のようなかたちで、レコード保存時に項目またはレコードページのウィンドウにエラーメッセージを表示します。
画面上にエラーメッセージを表示する要素で、レコードトリガーフローでのみ利用可能となっております。
入力規則のようなかたちで、レコード保存時に項目またはレコードページのウィンドウにエラーメッセージを表示します。
■画面
画面フローで利用可能な「画面」要素を利用して、条件に合致しない場合はカスタムのエラー画面を表示します。
なるべくユーザーに分かりやすいエラーメッセージとすることで、ユーザーがその後も安心してご利用頂けるかと思います。
画面フローで利用可能な「画面」要素を利用して、条件に合致しない場合はカスタムのエラー画面を表示します。
なるべくユーザーに分かりやすいエラーメッセージとすることで、ユーザーがその後も安心してご利用頂けるかと思います。
不正な値を入力した場合
画面フローの「画面」要素では、レコード項目と画面内で利用できる入力コンポーネントを使い、画面入力を行います。
レコード項目はレコードに直接値を設定できるため、その後の割り当て作業が不要になります。
入力コンポーネントは、画面要素後の処理で設定した値を利用したい場合(例えば条件分岐など)や画面のみで利用する場合に使います。
このレコード項目に対し、画面フローではデフォルトでは入力規則や数値の桁数チェックが行われません。
そのため、上記に引っかかる状態でレコードを保存した場合、フローのエラーとなってしまいます。
また、入力コンポーネントを使って後からレコード項目に値を入れる場合も、入力規則やレコード項目の定義に反した場合(データ型や桁数など)、フローのエラーとなります。
上記のような入力の制限がある場合、画面要素の後に条件分岐を付けてチェックをすることも可能かと思いますが、各入力コンポーネントに対し「入力を検証」を設定し、レコード保存前の入力チェックを行うことも可能です。
■入力を検証
画面内のコンポーネントタブ(以下画像①)内にある各入力コンポーネント(②)にて、入力のルールとエラーメッセージを定義できます(③)。
フロー版の入力規則のようなイメージです。
レコード項目はレコードに直接値を設定できるため、その後の割り当て作業が不要になります。
入力コンポーネントは、画面要素後の処理で設定した値を利用したい場合(例えば条件分岐など)や画面のみで利用する場合に使います。
このレコード項目に対し、画面フローではデフォルトでは入力規則や数値の桁数チェックが行われません。
そのため、上記に引っかかる状態でレコードを保存した場合、フローのエラーとなってしまいます。
また、入力コンポーネントを使って後からレコード項目に値を入れる場合も、入力規則やレコード項目の定義に反した場合(データ型や桁数など)、フローのエラーとなります。
上記のような入力の制限がある場合、画面要素の後に条件分岐を付けてチェックをすることも可能かと思いますが、各入力コンポーネントに対し「入力を検証」を設定し、レコード保存前の入力チェックを行うことも可能です。
■入力を検証
画面内のコンポーネントタブ(以下画像①)内にある各入力コンポーネント(②)にて、入力のルールとエラーメッセージを定義できます(③)。
フロー版の入力規則のようなイメージです。
エラーチェックは画面保存時に行われ、以下の様に対象の項目の下に赤字でエラーメッセージを表示します。
エラー条件の書き方は入力規則とほとんど同じなのですが、違う部分として「入力を検証」は条件の結果がFalseの場合にエラーとなります。(入力規則は結果がTrueの場合にエラー)
例えば、ある数値項目の制限として「最大14桁」とすると、それぞれ以下の様に書きます。
例えば、ある数値項目の制限として「最大14桁」とすると、それぞれ以下の様に書きます。
LEN( TEXT( {!testNum} )) > 14
「入力規則」の場合
NOT( LEN( TEXT( {!testNum} )) > 14 )
「入力を検証」の場合
このように、入力に制限がある各項目に対し「入力を検証」を設定することで、フローエラーを回避することが可能です。
(項目が多い場合1つ1つ設定するのはかなり大変ですが、頑張りましょう・・!)
1つ注意点として、「入力を検証」は全ての入力コンポーネントで使えるわけではありません。
(よく使いそうな入力コンポーネントの中だと、選択リスト、複数選択リストでは使えないようでした。)
また、項目が空白状態の場合だとチェックは実行されません。
そのため、条件に応じて項目を必須とする場合などは別途チェック用の項目を作るなど考慮が必要となります。
例えば、ある選択リスト項目が特定の値の時は必須入力とするテキスト項目がある場合、選択リストの入力コンポーネントは「入力を検証」が使えないため、テキスト項目側に上記条件の「入力の検証」を設定したとします。
この状態で、選択リスト値を特定の値にしてテキスト項目を空にした場合、「入力を検証」は行われないため、エラーは表示されず保存ができてしまいます。
こちらについてはHelpにて以下の通り記載されています。
(項目が多い場合1つ1つ設定するのはかなり大変ですが、頑張りましょう・・!)
1つ注意点として、「入力を検証」は全ての入力コンポーネントで使えるわけではありません。
(よく使いそうな入力コンポーネントの中だと、選択リスト、複数選択リストでは使えないようでした。)
また、項目が空白状態の場合だとチェックは実行されません。
そのため、条件に応じて項目を必須とする場合などは別途チェック用の項目を作るなど考慮が必要となります。
例えば、ある選択リスト項目が特定の値の時は必須入力とするテキスト項目がある場合、選択リストの入力コンポーネントは「入力を検証」が使えないため、テキスト項目側に上記条件の「入力の検証」を設定したとします。
この状態で、選択リスト値を特定の値にしてテキスト項目を空にした場合、「入力を検証」は行われないため、エラーは表示されず保存ができてしまいます。
こちらについてはHelpにて以下の通り記載されています。
実行時にユーザーがコンポーネントを空白のままにした場合、次のコンポーネントの値は検証されません。チェックボックス、チェックボックスグループ、選択肢ルックアップ、通貨、日付、日付と時間、ロングテキストエリア、複数選択リスト、数値、パスワード、選択リスト、ラジオボタン、テキスト。
まとめ
今回はフローでの例外処理に関して考えた内容をご紹介しました。
まとめると以下になります。
・例外処理を行うメリットは、エラー発生時の処理を事前に定義できること
→調査がしやすくなったり、データの整合性が保ちやすくなる。ユーザービリティを高める。
・障害パスやロールバックを積極的に利用する。
→障害パスが設定されていないと、エラー発生時にフロー全体が失敗しエラーメールのみが送信される。
→ロールバックが設定されていないと、複数レコード操作があった場合にデータの不整合が発生する可能性がある。
・1つのフロー内にトランザクションが異なるDMLが存在する場合、それぞれ例外処理を考慮する。
→ロールバックはトランザクション単位のため。
・条件分岐や入力を検証を利用してフローエラーになる前にエラーを検知する。
→事前にエラーを考慮した設計をすることでユーザーや管理者の負担を減らす。
・カスタムエラーメッセージや画面を利用してユーザーに分かりやすいエラーを表示する。
→ユーザーに分かりやすいエラーメッセージとすることで、安心して利用頂きやすくなる。
・画面を使う場合、入力規則、項目定義などの入力チェックは「入力を検証」を利用する。
→入力コンポーネントを使ってレコード保存時のフローエラーを防ぐ。
・入力を検証が使えない項目は、チェック用の項目を作るなど工夫が必要。
→現状選択リスト、複数選択リストでの利用は不可。また空白値はチェックが実行されない。
考慮が必要なエラーのパターンや適切な対応、どこまでやるかは案件によってさまざまかと思います。
今回ご紹介した各要素の使い方や使いどころは、あくまで1つの例としていただき、フローの内容に応じて使い分けてください。
こちらの内容が少しでも皆様のお役に立てば幸いです。
まとめると以下になります。
・例外処理を行うメリットは、エラー発生時の処理を事前に定義できること
→調査がしやすくなったり、データの整合性が保ちやすくなる。ユーザービリティを高める。
・障害パスやロールバックを積極的に利用する。
→障害パスが設定されていないと、エラー発生時にフロー全体が失敗しエラーメールのみが送信される。
→ロールバックが設定されていないと、複数レコード操作があった場合にデータの不整合が発生する可能性がある。
・1つのフロー内にトランザクションが異なるDMLが存在する場合、それぞれ例外処理を考慮する。
→ロールバックはトランザクション単位のため。
・条件分岐や入力を検証を利用してフローエラーになる前にエラーを検知する。
→事前にエラーを考慮した設計をすることでユーザーや管理者の負担を減らす。
・カスタムエラーメッセージや画面を利用してユーザーに分かりやすいエラーを表示する。
→ユーザーに分かりやすいエラーメッセージとすることで、安心して利用頂きやすくなる。
・画面を使う場合、入力規則、項目定義などの入力チェックは「入力を検証」を利用する。
→入力コンポーネントを使ってレコード保存時のフローエラーを防ぐ。
・入力を検証が使えない項目は、チェック用の項目を作るなど工夫が必要。
→現状選択リスト、複数選択リストでの利用は不可。また空白値はチェックが実行されない。
考慮が必要なエラーのパターンや適切な対応、どこまでやるかは案件によってさまざまかと思います。
今回ご紹介した各要素の使い方や使いどころは、あくまで1つの例としていただき、フローの内容に応じて使い分けてください。
こちらの内容が少しでも皆様のお役に立てば幸いです。