SOAP フォルトの処理
このトピックでは、Web サービス内および Web クライアント内でフォルトを処理する方法を説明します。
TRY-CATCH の使用法 も参照してください。
SOAPPREFIX パラメータは、すべての SOAP フォルトで使用する接頭語に作用します。"SOAP エンベロープ接頭語の指定" を参照してください。
Web サービスでの既定のフォルト処理
既定では、InterSystems IRIS® データ・プラットフォーム Web サービスでエラーが検出されると、フォルトを含む標準の SOAP メッセージが返されます。以下に例を示します (SOAP 1.1 の場合)。この例では、SOAP エンベロープは省略されています。
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Server Application Error</faultstring>
<detail>
<error xmlns='https://www.myapp.org' >
<text>ERROR #5002: ObjectScript error: <DIVIDE>zDivide^FaultEx.Service.1</text>
</error>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
InterSystems IRIS Web サービスでカスタムの SOAP フォルトを返す方法
カスタムの SOAP フォルトを作成して返すには、エラーをトラップする適切なコードの領域内で以下の手順を実行します。
-
適切な情報を含むフォルト・オブジェクトを作成します。そのためには、Web サービスのメソッドのうち、MakeFault()、MakeFault12()、MakeSecurityFault()、MakeStatusFault() のいずれかを呼び出します。これらは以下のサブセクションで説明しています。
または、手動でフォルト・オブジェクトを作成することもできます。その手順については、このトピックで後述します。
-
フォルト・オブジェクトを引数として渡すことにより、Web サービスの ReturnFault() メソッドを呼び出します。ReturnFault()) が呼び出し元に戻ることはありません。このメソッドは、フォルトを送信し、Web メソッドの処理を終了するだけです。
以下に例を示します。
Method Divide(arg1 As %Numeric, arg2 As %Numeric) As %Numeric [ WebMethod ]
{
Try {
Set ans=arg1 / arg2
} Catch {
//<detail> element must contain element(s) or whitespace
//specify this element by passing valid XML as string argument to MakeFault()
set mydetail="<mymessage>Division error detail</mymessage>"
set fault=..MakeFault($$$FAULTServer,"Division error",mydetail)
// ReturnFault must be called to send the fault to the client.
// ReturnFault will not return here.
Do ..ReturnFault(fault)
}
Quit ans
}
フォルトを作成するメソッド
classmethod MakeFault(pFaultCode As %String,
pFaultString As %String,
pDetail As %String = "",
pFaultActor As %String = "") as %SOAP.Fault
SOAP 1.1 に適したフォルト・オブジェクトを返します。以下はその説明です。
-
pFaultCode は、SOAP フォルトの <faultcode> 要素内で使用されます。このプロパティを、"SOAP フォルト・コードのマクロ" に記載されている SOAP 1.1 マクロのいずれかに設定します。
-
pFaultString は、SOAP フォルトの <faultstring> 要素内で使用されます。ユーザが確認できるように、フォルトの理由を示す文字列を指定します。
-
pDetail は、SOAP フォルトの <detail> 要素内で使用されます。これを使用して、フォルトの原因に関する情報を指定します。
指定した場合は、この引数には、<detail> 要素内で使用できる有効な XML を含む文字列を指定する必要があります。InterSystems IRIS では、指定した文字列が有効かどうかの確認は行われず、このチェックはアプリケーションの担当です。
-
pFaultActor は、フォルト発生の原因となった SOAP メッセージ・パスの SOAP ノードの URI を指定します。
SOAP メッセージが SOAP メッセージ・パスの複数のノードを通過する場合に、エラーの原因となったノードをクライアントで確認する必要があるときには、これが役立ちます。この高度な使用法については、このドキュメントでは説明していません。
classmethod MakeFault12(pFaultCode As %String,
pFaultString As %String,
pDetail As %String = "",
pFaultActor As %String = "") as %SOAP.Fault
SOAP 1.2 に適したフォルト・オブジェクトを返します。このメソッドは、Web サービスの SoapVersion プロパティが "1.2" の場合にのみ使用します。InterSystems IRIS で要求メッセージの SOAP バージョンがどのように扱われるかの詳細は、"Web サービスのパラメータの指定" を参照してください。
また、これらの引数の詳細は、MakeFault() に関する説明を参照してください。
classmethod MakeSecurityFault(pFaultCode As %String,
securityNamespace As %String) as %SOAP.Fault
セキュリティの失敗に適したフォルト・オブジェクトを返します。FaultCode を、"FailedAuthentication"、"FailedCheck"、"InvalidSecurity"、"InvalidSecurityToken"、"SecurityTokenUnavailable"、"UnsupportedAlgorithm"、"UnsupportedSecurityToken" のいずれかに指定します。
このセキュリティ・フォルトのネームスペースは、SecurityNamespace プロパティに含まれています。
classmethod MakeStatusFault(pFaultCode As %String,
pFaultString As %String,
pStatus As %Status = "",
pFaultActor As %String = "") as %SOAP.Fault
%StatusOpens in a new tab オブジェクトの値に基づいてフォルト・オブジェクトを返します。
pStatus は、使用する %StatusOpens in a new tab オブジェクトです。
その他の引数の詳細は、MakeFault() に関する説明を参照してください。
SOAP フォルト・コードのマクロ
以下のテーブルに示すように、SOAP インクルード・ファイル (%soap.inc) では、一部の標準の SOAP フォルト・コードのマクロが定義されます。これらのマクロを使用して、SOAP フォルト・コードを指定できます。このテーブルは、各マクロが適用される SOAP のバージョン (複数可) を示しています。
マクロ | SOAP バージョン | このマクロを使用する場合 |
---|---|---|
$$$FAULTVersionMismatch | 1.1 および 1.2 | Web サービスが、必要なエンベロープ要素情報項目ではなく、無効な要素情報項目を含む SOAP メッセージを受け取った場合
ネームスペースまたはローカル名のいずれかが一致しない、不一致が発生した場合 |
$$$FAULTMustUnderstand | 1.1 および 1.2 | Web サービスが、mustUnderstand="true" というマークが付いた予期しない要素を含む SOAP メッセージを受け取った場合 |
$$$FAULTServer | 1.1 | サーバ側で他のエラーが発生した場合 |
$$$FAULTClient | 1.1 | クライアントが、不完全なまたは誤った要求をした場合 |
$$$FAULTDataEncodingUnknown | 1.2 | 受信者にとって不明なデータ・エンコードで引数がエンコードされている場合 |
$$$FAULTSender | 1.2 | 送信者が不完全な、誤った、またはサポートされていない要求をした場合 |
$$$FAULTReceiver | 1.2 | 何らかの一時的な状態 (メモリ不足など) のために、受信者がメッセージを処理できない場合 |
フォルト・オブジェクトの手動作成
前のセクションの手順よりも詳細な管理を行う必要がある場合は、以下の手順でカスタムの SOAP フォルトを作成して返すことができます。
-
フォルト・オブジェクトを手動で作成します。
そのためには、%SOAP.FaultOpens in a new tab (SOAP 1.1 の場合) または %SOAP.Fault12Opens in a new tab (SOAP 1.2 の場合) のインスタンスを作成し、そのプロパティを設定します。手順は以降のセクションを参照してください。
Note:すべての場合に %SOAP.FaultOpens in a new tab を使用できます。Web サービスが SOAP 1.2 要求を受信し、フォルトを返す必要がある場合は、Web サービスによってそのフォルトが SOAP 1.2 形式に自動的に変換されます。
-
フォルト・オブジェクトを引数として渡すことにより、Web サービスの ReturnFault() メソッドを呼び出します。ReturnFault()) が呼び出し元に戻ることはありません。このメソッドは、フォルトを送信し、Web メソッドの処理を終了するだけです。
SOAP 1.1 フォルト
このセクションでは、SOAP 1.1 フォルトを表す %SOAP.FaultOpens in a new tab に関する情報を提供します。このセクションでは、以下の項目について説明します。
SOAP フォルトの例
参照のために、SOAP エンベロープを含めた SOAP 1.1 フォルトの例を以下に示します。
<SOAP-ENV:Envelope
xmlns:SOAP-ENV='https://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xmlns:s='https://www.w3.org/2001/XMLSchema'
xmlns:flt="https://myfault.org" >
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Division error</faultstring>
<detail><mymessage>Division error detail</mymessage></detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
%SOAP.Fault のプロパティ
InterSystems IRIS では、SOAP 1.1 フォルトを %SOAP.FaultOpens in a new tab のインスタンスとして表します。これには、以下のプロパティがあります。
SOAP フォルトの <detail> 要素内で使用されます。これを使用して、フォルトの原因に関する情報を指定します。
指定した場合は、この引数には、<detail> 要素内で使用できる有効な XML を含む文字列を指定する必要があります。InterSystems IRIS では、指定した文字列が有効かどうかの確認は行われず、このチェックはアプリケーションの担当です。
SOAP フォルトの <faultcode> 要素内で使用されます。このプロパティを、"SOAP フォルト・コードのマクロ" に記載されている SOAP 1.1 マクロのいずれかに設定します。
SOAP フォルトの <faultstring> 要素内で使用されます。ユーザが確認できるように、フォルトの理由を示す文字列を指定します。
フォルト発生の原因となった SOAP メッセージ・パスの SOAP ノードの URI を指定します。
SOAP メッセージが SOAP メッセージ・パスの複数のノードを通過する場合に、エラーの原因となったノードをクライアントで確認する必要があるときには、これが役立ちます。この高度な使用法については、このドキュメントでは説明していません。
SOAP フォルトのエンベロープに追加されるネームスペース接頭語宣言を指定します。以下の形式の値を使用します。
xmlns:prefix="namespace"
prefix は接頭語で、namespace はネームスペース URI です。
以下はその例です。
set fault.faultPrefixDefinition = "xmlns:FLT=""https://myfault.com"""
%SOAP.FaultOpens in a new tab クラスには、フォルト・オブジェクトを文字列として返す AsString() メソッドもあります。
SOAP 1.2 フォルト
このセクションでは、SOAP 1.2 フォルトを表す %SOAP.Fault12Opens in a new tab および関連するクラスに関する情報を提供します。このセクションでは、以下の項目について説明します。
SOAP フォルトの例
参照のために、SOAP エンベロープを含めた SOAP 1.2 フォルトの例を以下に示します。
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="https://www.w3.org/2003/05/soap-envelope" xmlns:flt="https://myfault.org">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<SOAP-ENV:Code>
<SOAP-ENV:Value>SOAP-ENV:Receiver</SOAP-ENV:Value>
</SOAP-ENV:Code>
<SOAP-ENV:Reason>
<SOAP-ENV:Text xml:lang="en">Division error</SOAP-ENV:Text>
<SOAP-ENV:Text xml:lang="it">Errore di applicazione</SOAP-ENV:Text>
<SOAP-ENV:Text xml:lang="es">Error del uso</SOAP-ENV:Text>
</SOAP-ENV:Reason>
<SOAP-ENV:Detail><mymessage>Division error detail</mymessage></SOAP-ENV:Detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
%SOAP.Fault12 のプロパティ
%SOAP.Fault12Opens in a new tab クラスは SOAP 1.2 フォルトを表します。このクラスには、以下のプロパティがあります。
次のセクションで説明している %SOAP.Fault12.CodeOpens in a new tab のインスタンス。
SOAP フォルトの <detail> 要素内で使用されます。これを使用して、フォルトの原因に関する情報を指定します。
指定した場合は、この引数には、<detail> 要素内で使用できる有効な XML を含む文字列を指定する必要があります。InterSystems IRIS では、指定した文字列が有効かどうかの確認は行われず、このチェックはアプリケーションの担当です。
フォルト発生の原因となった SOAP メッセージ・パスの SOAP ノードの URI を指定します。宛先ノードの場合はオプションです。
SOAP メッセージが SOAP メッセージ・パスの複数のノードを通過する場合に、エラーの原因となったノードをクライアントで確認する必要があるときには、これが役立ちます。SOAP のこの高度な使用法についての説明は、このドキュメントの対象ではありません。
次のセクションで説明している %SOAP.Fault12.TextOpens in a new tab のインスタンスのリスト。各インスタンスには、理由文字列、および理由文字列の言語または局所性を示す言語コードが含まれています。これらは、<Reason> 要素内で使用されます。
ノードが動作していた役割。Node に関する前述の備考を参照してください。
SOAP フォルトのエンベロープに追加されるネームスペース接頭語宣言を指定します。以下の形式の値を使用します。
xmlns:prefix="namespace"
prefix は接頭語で、namespace はネームスペース URI です。
以下はその例です。
set fault.faultPrefixDefinition = "xmlns:FLT=""https://myfault.com"""
%SOAP.Fault12Opens in a new tab クラスには、フォルト・オブジェクトを文字列として返す AsString() メソッドもあります。
%SOAP.Fault12.Code のプロパティ
%SOAP.Fault12Opens in a new tab のインスタンスの Code プロパティの値として %SOAP.Fault12.CodeOpens in a new tab を使用します。%SOAP.Fault12.CodeOpens in a new tab クラスには以下のプロパティがあります。
オプションのサブコードです。
指定する値は、サブコードを指定したかどうかによって異なります。
-
サブコードを使用した場合、Value には qname と指定します。
-
サブコードを使用していない場合、Value には、"SOAP フォルト・コードのマクロ" に記載された SOAP 1.2 マクロのいずれかを指定します。
%SOAP.Fault12.Text のプロパティ
%SOAP.Fault12Opens in a new tab のインスタンスの Reason プロパティのリスト要素として、%SOAP.Fault12.TextOpens in a new tab を使用します。%SOAP.Fault12.TextOpens in a new tab クラスには以下のプロパティがあります。
ユーザが確認できるように、フォルトの理由を示す文字列。
フォルト・テキストが表されている言語または局所性に対応するコード。詳細は、W3 の Web サイト (https://www.w3.org/Opens in a new tab) を参照してください。
フォルト発生時の WS-Addressing ヘッダ要素の追加
フォルトの発生時に WS-Addressing ヘッダ要素を追加するように InterSystems IRIS Web サービスを設定できます。そのためには、Web サービスのフォルト処理に次の手順を追加します。
-
フォルト発生時に使用するフォルトの宛先とフォルトのアクションを選択します。
-
これらを引数として使用して、%SOAP.Addressing.PropertiesOpens in a new tab クラスの GetDefaultResponseProperties() メソッドを呼び出します。このメソッドからは、一般に必要となる値が設定された %SOAP.Addressing.PropertiesOpens in a new tab のインスタンスが返ります。
-
必要に応じて、%SOAP.Addressing.PropertiesOpens in a new tab のインスタンスのその他のプロパティを設定します。
詳細は、%SOAP.Addressing.PropertiesOpens in a new tab のクラス・ドキュメントを参照してください。
-
Web サービスの FaultAddressing プロパティを %SOAP.Addressing.PropertiesOpens in a new tab のインスタンスと等しくなるように設定します。
フォルト発生時のその他のヘッダ要素の追加
フォルト発生時にカスタムのヘッダ要素を追加するように InterSystems IRIS Web サービスを設定することもできます。このカスタムのヘッダ要素は、前のセクションで説明したオプションに追加するオプションとすることができるほか、それらのオプションに代わるものとすることもできます。以下はその方法です。
-
%SOAP.HeaderOpens in a new tab のサブクラスを作成します。このサブクラスで、追加データを設定したプロパティを追加します。
"カスタム・ヘッダ要素の追加と使用" を参照してください。
-
このトピックで既に取り上げた Web サービスのフォルト処理に次の手順を追加します。
-
ヘッダ・サブクラスのインスタンスを作成します。
Note:このようなクラス名になっていても、このオブジェクトはヘッダ全体を表しているわけではなく、実際には SOAP ヘッダ要素です。個々の SOAP メッセージには、複数の要素で構成したヘッダが 1 つあります。
-
必要に応じて、そのプロパティを設定します。
-
Web サービスの FaultHeaders 配列プロパティにこのヘッダ要素を挿入します。そのためには、そのプロパティの SetAt() を呼び出します。指定したキーはヘッダのメイン要素名として使用されます。
-
例えば、次のようなカスタムのヘッダ・クラスがあるとします。
Class Fault.CustomHeader Extends %SOAP.Header
{
Parameter XMLTYPE = "CustomHeaderElement";
Property SubElement1 As %String;
Property SubElement2 As %String;
Property SubElement3 As %String;
}
前述の Web メソッドを以下のように変更します。
Method DivideAlt(arg1 As %Numeric, arg2 As %Numeric) As %Numeric [ WebMethod ]
{
Try {
Set ans=arg1 / arg2
} Catch {
//<detail> element must contain element(s) or whitespace
//specify this element by passing valid XML as string argument to MakeFault()
set mydetail="<mymessage>Division error detail</mymessage>"
set fault=..MakeFault($$$FAULTServer,"Division error",mydetail)
//Set fault header
Set header=##class(CustomHeader).%New()
Set header.SubElement1="custom fault header element"
Set header.SubElement2="another custom fault header element"
Set header.SubElement3="yet another custom fault header element"
Do ..FaultHeaders.SetAt(header,"CustomFaultElement")
// ReturnFault must be called to send the fault to the client.
// ReturnFault will not return here.
Do ..ReturnFault(fault)
}
Quit ans
}
Web クライアントから Divide() Web メソッドを呼び出して、分母として 0 を使用すると、Web サービスは次のように応答します。
<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='https://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xmlns:s='https://www.w3.org/2001/XMLSchema' xmlns:flt="https://myfault.org" >
<SOAP-ENV:Header>
<CustomHeaderElement xmlns:hdr="https://www.mynamespace.org">
<SubElement1>custom fault header element</SubElement1>
<SubElement2>another custom fault header element</SubElement2>
<SubElement3>yet another custom fault header element</SubElement3>
</CustomHeaderElement>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
...
ここでは、見やすくするために改行を追加してあります。
InterSystems IRIS Web クライアントでの SOAP フォルトおよびその他のエラーの処理
InterSystems IRIS Web クライアントでは、TRY-CATCH メカニズム、または従来の $ZTRAP メカニズムを使用できます。
どちらの場合も、InterSystems IRIS Web クライアントがエラーを受信すると、特殊変数 $ZERROR と %objlasterror が InterSystems IRIS で次のように設定されます。
-
エラーが SOAP フォルトの場合、$ZERROR の値は <ZSOAP> で始まります。また %objlasterror には、受信した SOAP フォルトから形成されるステータス・エラーが格納されます。
また、クライアント・インスタンスには SoapFault という名前のプロパティがあります。これは、Web サービスで使用している SOAP バージョンに応じて、%SOAP.FaultOpens in a new tab または %SOAP.Fault12Opens in a new tab のインスタンスになります。このプロパティでこの情報を使用できます。%SOAP.FaultOpens in a new tab および %SOAP.Fault12Opens in a new tab の詳細は、前のセクションを参照してください。
-
エラーが SOAP フォルトではない場合、標準のエラー処理を行う必要があります (通常は $ZERROR を使用)。処理方法はユーザが指定します。
例 1 : Try-Catch
以下のメソッドでは、TRY-CATCH を使用しています。
ClassMethod Divide(arg1 As %Numeric, arg2 As %Numeric) As %Numeric
{
Set $ZERROR=""
Set client=##class(FaultClient.DivideSoap).%New()
Try {
Set ans=client.Divide(arg1,arg2)
}
Catch {
If $ZERROR["<ZSOAP>" {
Set ans=%objlasterror
}
Else {
Set ans=$$$ERROR($$$ObjectScriptError,$ZERROR)
}
}
Quit ans
}
このメソッドでは、%systemInclude インクルード・ファイルで定義されているシステム・マクロを使用しているため、このメソッドを含むクラスの先頭は以下のようになります。
Include %systemInclude
例 2 : $ZTRAP
次の例では、従来の $ZTRAP メカニズムを使用しています。この場合、InterSystems IRIS Web クライアントがエラーを受信すると、特殊変数 $ZTRAP が示すラベル位置に制御が移動します (そのラベルが定義されている場合)。
ClassMethod DivideWithZTRAP(arg1 As %Numeric = 1, arg2 As %Numeric = 2) As %Numeric
{
Set $ZERROR=""
Set $ZTRAP="ERRORTRAP"
Set client=##class(FaultClient.DivideSoap).%New()
Set ans=client.Divide(arg1,arg2)
Quit ans
//control goes here in case of error
ERRORTRAP
if $ZERROR["<ZSOAP>"
{
quit client.SoapFault.Detail
}
else
{
quit %objlasterror
}
}
SSL ハンドシェイクのエラー
InterSystems IRIS Web クライアントが SSL 接続を使用しているときに SSL ハンドシェイク・エラーが発生した場合、クライアントの SSLError プロパティにその SSL エラーを説明するテキストが格納されます。