Flex Gateway新着情報
Governance新着情報
Monitoring API ManagerJava の例外処理プロセスでは何が起こったのかを理解するためにソースコードを確認したり、エラーを強制的に発生させたりする必要がありますが、Mule 4 ではこれ以外の方法も使用できるようになりました。Java の Throwable
エラーや例外も引き続き使用できますが、Mule 4 では処理しやすいエラーの概念が正式に導入されています。スローされる可能性のあるエラーの種類を各コンポーネントで宣言して、設計の時点で潜在的なエラーを識別できるようになりました。
実行に失敗すると、Mule に次のコンポーネントを含むエラーが示されます。
問題の説明。
問題の特性を表す種類。
原因 (失敗を引き起こした根本的な Java Throwable
)。
エラーメッセージ (省略可能)。問題に関する Mule の適切なメッセージが記載されます。
たとえば、HTTP 要求に失敗して 401 状況コードが表示された場合、Mule エラーに次の情報が示されます。
Description: HTTP GET on resource ‘http://localhost:36682/testPath’ failed: unauthorized (401) Type: HTTP:UNAUTHORIZED Cause: a ResponseValidatorTypedException instance Error Message: { "message" : "Could not authorize the user." }
上記の例では、エラーの種類は単純に UNAUTHORIZED
ではなく HTTP:UNAUTHORIZED
です。エラーの種類が名前空間と識別子の両方で構成されるため、ドメインからその種類を判別することができます (HTTP:NOT_FOUND
、FILE:NOT_FOUND
など)。名前空間はそのコネクタによって定義されますが、コアランタイムエラーの名前空間は暗黙的なため、MULE:EXPRESSION
と EXPRESSION
は同一とみなされます。
エラーの種類のもう一つの重要な特徴は、親種別のある可能性があることです。たとえば、HTTP:UNAUTHORIZED
は親として MULE:CLIENT_SECURITY
を持ち、さらにその親として MULE:SECURITY
があります。このため、エラーの種類がグローバルなエラーの細部であることがわかります。つまり、広範なセキュリティ問題の 1 つにクライアントセキュリティエラーがあり、その 1 つに HTTP 未承認エラーがあるということです。
こうした階層により、大まかなルーティングが可能になります。たとえば、MULE:SECURITY
のハンドラーが HTTP 未承認エラーと OAuth エラーの両方をキャッチします。以下は、コアランタイムがどのような階層になっているかを示しています。
どのエラーも一般的なエラーと CRITICAL
エラーのどちらかに該当しますが、後者は極めて深刻なため処理することができません。一般的な階層の最上位が ANY
で、その下位の全種類がこれに該当します。
ここで重要な点は、失敗の明確な理由が見つからない場合に使用される UNKNOWN
という種類に注意することです。このエラーは ANY
種類経由でしか処理できないため、今後既存のアプリケーションの動作を変更することなく、不明なエラーを特定できるようになります。
コネクタについては、各コネクタがそのコアランタイムエラーを考慮して各自のエラー種類階層を定義しますが、CONNECTIVITY
と RETRY_EXHAUSTED
の 2 種類はすべてのコネクタに共通するため、常に存在します。
Mule 4 では、error-handler
コンポーネントを導入してエラー処理が再設計されています。このコンポーネントには任意の数の内部ハンドラーを含めることができ、最初に一致したハンドラーにエラーをルーティングできます。これらのハンドラーに該当するのが on-error-continue
や on-error-propagate
で、どちらもエラーの種類 (あるいは数種類のエラー) または式 (高度なユースケースの場合) との照合をサポートしています。こうしたハンドラーは、Mule 3 の選択例外 (choice-exception-strategy
)、キャッチ例外 (catch-exception-strategy
)、ロールバック例外 (rollback-exception-strategy
) 戦略によく似ていますが、はるかにシンプルで一貫しています。
Mule 4 でエラーが生じると、エラーハンドラーが実行され、最初に一致したハンドラーにエラーがルーティングされます。この時点でエラーが検査されるため、使用するコンポーネント (Flow または Try スコープなど) に応じたハンドラーを実行して処理できます。
on-error-continue
が実行され、実行の結果がそのオーナーの結果として (オーナーが実行を正常に完了したかのように) 使用されます。
また、この時点のすべてのトランザクションがコミットされます。
on-error-propagate
はすべてのトランザクションをロールバックしてから実行され、その結果が使用されて既存のエラーが再度スローされます。つまり、そのオーナーは「失敗した」とみなされます。
HTTP リスナーが、HTTP 要求を実行する別のフローへの Flow Reference コンポーネントをトリガーする、次のアプリケーションについて考えてみます。メッセージの受信時にすべてうまくいけば (下図の 1)、参照がトリガーされ (2)、要求が実行されて (3)、応答を正常に受信します (HTTP 状況コード 200) (4)。
エラーハンドラーの設定が inner-flow
であるため HTTP 要求に失敗し、HTTP:NOT_FOUND
エラーが表示された場合 (下図の 3)、エラーが伝搬され (4)、Flow Reference コンポーネントが失敗します (2)。ただし、primary-flow
によって on-error-continue
を使用してエラーが処理されるため、含まれている Logger が実行され (5)、正常な応答 (HTTP 状況コード 200) が返されます (6)。
要求に失敗し、未承認エラーが表示された場合は (3)、on-error-continue
により inner-flow
が処理を行い、ファイルから静的コンテンツを取得します (4)。そして、Flow Reference コンポーネントも正常に行われ (2)、正常な応答 (HTTP 状況コード 200) が返されます (5)。
では、HTTP 要求で別のエラーが生じた場合はどうでしょうか? このフローには NOT_FOUND
エラーと UNAUTHORIZED
エラーのハンドラーしかありませんが、デフォルトで他のエラーも伝搬します。つまり、スローされたエラーに一致するハンドラーがなければ、エラーが再びスローされます。たとえば、要求に失敗し、「メソッドが許可されていません」というエラーが表示された場合 (3)、このエラーが伝搬され、Flow Reference コンポーネントが失敗し (2)、この伝搬により応答も失敗します (4)。
上記のシナリオを回避するためには、最後のハンドラーを HTTP:UNAUTHORIZED
ではなく、ANY
と照合するようにします。以下は、HTTP
要求で生じる可能性のある全エラーがどのように提示されるかを示しています。
式を使用してエラーを照合することもできます。たとえば、エラーの処理時に Mule エラーを使用できるため、このエラーを使用してすべてのエラーを HTTP 名前空間と照合することができます。
Mule 3 では概してエラーをフローレベルでしか処理できないため、エラーに対処するためにはフローにロジックを抽出する必要があります。Mule 4 では、フロー内で内部コンポーネントのエラーのみを処理する Try スコープが導入されました。このスコープは旧来の Transactional スコープの後継で、トランザクションもサポートします。
前の例では、On Error Propagate コンポーネントがデータベース接続エラーを伝播するように設定されているため、try
が失敗して、フローのエラーハンドラーが実行されます。
On Error Continue コンポーネントは、他のすべてのエラーを処理するように設定されています。この場合、Try スコープの実行は正常に完了し、フローの実行が次のプロセッサーである HTTP Request 操作に引き継がれます。
Mule 4 では、デフォルトのエラーをカスタムエラーにマップできるようになりました。Try スコープは便利ですが、同一のコンポーネントがいくつかあり、それぞれのエラーを区別したい場合、これらのエラーに Try を使用するとアプリケーションがわかりづらくなることがあります。この場合は代わりに、各コンポーネントにエラーマッピングを追加することが考えられます。つまり、コンポーネントからのすべてまたは一定のエラーストリーミングが任意の別のエラーにマップされるようにします。たとえば、それぞれ HTTP 要求コンポーネントを使用する 2 つの API の結果を集約する場合、デフォルトでは API 1 と API 2 のエラーが同じため、API ごとに区別したいことがあります。
最初の要求からのエラーをカスタムの API_1
エラーにマップし、2 つ目の要求のエラーを API_2
にマップすれば、これらのエラーを異なるハンドラーにルーティングできます。次の例では、HTTP:INTERNAL_SERVER_ERROR
がマップされるため、API がダウンしたときにそれぞれ異なる処理ポリシーが適用されます (1 つ目の API はエラーの伝搬、2 つ目の API はエラーの処理)。