Caché での Web サービスおよび Web クライアントの作成
SOAP フォルトの処理
[Home] [Back] [Next]
InterSystems: The power behind what matters   
Class Reference   
Search:    

この章では、Web サービス内および Web クライアント内でフォルトを処理する方法を説明します。

エラー処理の詳細は、ドキュメント "Caché ObjectScript の使用法" のエラーに関する章を参照してください。
SOAPPREFIX パラメータは、すべての SOAP フォルトで使用される接頭語に作用します。Caché Web サービスの調整 の章の SOAP エンベロープ接頭語の指定 を参照してください。
Web サービスでの既定のフォルト処理
既定では、Caché 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='http://www.myapp.org' >
       <text>ERROR #5002: Cache error: <DIVIDE>zDivide^FaultEx.Service.1</text>
     </error>
  </detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
Caché Web サービスでカスタムの SOAP フォルトを返す方法
カスタムの SOAP フォルトを作成して返すには、エラーをトラップする適切なコードの領域内で以下の手順を実行します。
  1. 適切な情報を含むフォルト・オブジェクトを作成します。そのためには、Web サービスのメソッドのうち、MakeFault()MakeFault12()MakeSecurityFault()MakeStatusFault() のいずれかを呼び出します。これらは以下のサブセクションで説明しています。
    または、手動でフォルト・オブジェクトを作成することもできます。その手順については、この章で後述します。
  2. フォルト・オブジェクトを引数として渡すことにより、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
}
フォルトを作成するメソッド
MakeFault()
classmethod MakeFault(pFaultCode As %String, 
                      pFaultString As %String, 
                      pDetail As %String = "", 
                      pFaultActor As %String = "") as %SOAP.Fault
SOAP 1.1 に適したフォルト・オブジェクトを返します。以下はその説明です。
MakeFault12()
classmethod MakeFault12(pFaultCode As %String, 
            pFaultString As %String,
            pDetail As %String = "", 
            pFaultActor As %String = "") as %SOAP.Fault
SOAP 1.2 に適したフォルト・オブジェクトを返します。このメソッドは、Web サービスの SoapVersion プロパティが "1.2" の場合にのみ使用します。Caché で要求メッセージの SOAP バージョンを処理する方法の詳細は、このドキュメントで前述した Web サービスのパラメータの指定 を参照してください。
また、これらの引数の詳細は、MakeFault() に関する説明を参照してください。
MakeSecurityFault()
classmethod MakeSecurityFault(pFaultCode As %String, 
                              securityNamespace As %String) as %SOAP.Fault
セキュリティの失敗に適したフォルト・オブジェクトを返します。FaultCode を、"FailedAuthentication""FailedCheck""InvalidSecurity""InvalidSecurityToken""SecurityTokenUnavailable""UnsupportedAlgorithm""UnsupportedSecurityToken" のいずれかに指定します。
このセキュリティ・フォルトのネームスペースは、SecurityNamespace プロパティに含まれています。
MakeStatusFault()
classmethod MakeStatusFault(pFaultCode As %String, 
                            pFaultString As %String, 
                            pStatus As %Status = "", 
                            pFaultActor As %String = "") as %SOAP.Fault
%Status オブジェクトの値に基づいてフォルト・オブジェクトを返します。
pStatus は、使用する %Status オブジェクトです。
その他の引数の詳細は、MakeFault() に関する説明を参照してください。
SOAP フォルト・コードのマクロ
以下のテーブルに示すように、SOAP インクルード・ファイル (%soap.inc) では、一部の標準の SOAP フォルト・コードのマクロが定義されます。これらのマクロを使用して、SOAP フォルト・コードを指定できます。このテーブルは、各マクロが適用される SOAP のバージョン (複数可) を示しています。
SOAP フォルト・コードの Caché ObjectScript マクロ
マクロ 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 フォルトを作成して返すことができます。
  1. フォルト・オブジェクトを手動で作成します。
    そのためには、%SOAP.Fault (SOAP 1.1 の場合) または %SOAP.Fault12 (SOAP 1.2 の場合) のインスタンスを作成し、そのプロパティを設定します。手順は以降のセクションを参照してください。
    注意:
    すべての場合に %SOAP.Fault を使用できます。Web サービスが SOAP 1.2 要求を受信し、フォルトを返す必要がある場合は、Web サービスによってそのフォルトが SOAP 1.2 形式に自動的に変換されます。
  2. フォルト・オブジェクトを引数として渡すことにより、Web サービスの ReturnFault() メソッドを呼び出します。ReturnFault()) が呼び出し元に戻ることはありません。このメソッドは、フォルトを送信し、Web メソッドの処理を終了するだけです。
SOAP 1.1 フォルト
このセクションでは、SOAP 1.1 フォルトを表す %SOAP.Fault に関する情報を提供します。このセクションでは、以下の項目について説明します。
SOAP フォルトの例
参照のために、SOAP エンベロープを含めた SOAP 1.1 フォルトの例を以下に示します。
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' 
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
xmlns:s='http://www.w3.org/2001/XMLSchema' 
xmlns:flt="http://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 のプロパティ
Caché では、SOAP 1.1 フォルトを %SOAP.Fault のインスタンスとして表します。これには、以下のプロパティがあります。
detail
SOAP フォルトの <detail> 要素内で使用されます。これを使用して、フォルトの原因に関する情報を指定します。
指定した場合は、この引数には、<detail> 要素内で使用できる有効な XML を含む文字列を指定する必要があります。Caché では、指定した文字列が有効かどうかの確認は行われず、このチェックはアプリケーションの担当です。
faultcode
SOAP フォルトの <faultcode> 要素内で使用されます。このプロパティを、この章で前述の SOAP フォルト・コードのマクロ に記載されている SOAP 1.1 マクロのいずれかに設定します。
faultstring
SOAP フォルトの <faultstring> 要素内で使用されます。ユーザが確認できるように、フォルトの理由を示す文字列を指定します。
faultactor
フォルト発生の原因となった SOAP メッセージ・パスの SOAP ノードの URI を指定します。
SOAP メッセージが SOAP メッセージ・パスの複数のノードを通過する場合に、エラーの原因となったノードをクライアントで確認する必要があるときには、これが役立ちます。この高度な使用法については、このドキュメントでは説明していません。
faultPrefixDefinition
SOAP フォルトのエンベロープに追加されるネームスペース接頭語宣言を指定します。以下の形式の値を使用します。
xmlns:prefix="namespace"
prefix は接頭語で、namespace はネームスペース URI です。
以下はその例です。
 set fault.faultPrefixDefinition = "xmlns:FLT=""http://myfault.com"""
%SOAP.Fault クラスには、フォルト・オブジェクトを文字列として返す AsString() メソッドもあります。
SOAP 1.2 フォルト
このセクションでは、SOAP 1.2 フォルトを表す %SOAP.Fault12 および関連するクラスに関する情報を提供します。このセクションでは、以下の項目について説明します。
SOAP フォルトの例
参照のために、SOAP エンベロープを含めた SOAP 1.2 フォルトの例を以下に示します。
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:flt="http://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.Fault12 クラスは SOAP 1.2 フォルトを表します。このクラスには、以下のプロパティがあります。
Code
次のセクションで説明している %SOAP.Fault12.Code のインスタンス。
Detail
SOAP フォルトの <detail> 要素内で使用されます。これを使用して、フォルトの原因に関する情報を指定します。
指定した場合は、この引数には、<detail> 要素内で使用できる有効な XML を含む文字列を指定する必要があります。Caché では、指定した文字列が有効かどうかの確認は行われず、このチェックはアプリケーションの担当です。
Node
フォルト発生の原因となった SOAP メッセージ・パスの SOAP ノードの URI を指定します。宛先ノードの場合はオプションです。
SOAP メッセージが SOAP メッセージ・パスの複数のノードを通過する場合に、エラーの原因となったノードをクライアントで確認する必要があるときには、これが役立ちます。SOAP のこの高度な使用法についての説明は、このドキュメントの対象ではありません。
Reason
次のセクションで説明している %SOAP.Fault12.Text のインスタンスのリスト。各インスタンスには、理由文字列、および理由文字列の言語または局所性を示す言語コードが含まれています。これらは、<Reason> 要素内で使用されます。
Role
ノードが動作していた役割。Node に関する前述の備考を参照してください。
faultPrefixDefinition
SOAP フォルトのエンベロープに追加されるネームスペース接頭語宣言を指定します。以下の形式の値を使用します。
xmlns:prefix="namespace"
prefix は接頭語で、namespace はネームスペース URI です。
以下はその例です。
 set fault.faultPrefixDefinition = "xmlns:FLT=""http://myfault.com"""
%SOAP.Fault12 クラスには、フォルト・オブジェクトを文字列として返す AsString() メソッドもあります。
%SOAP.Fault12.Code のプロパティ
%SOAP.Fault12 のインスタンスの Code プロパティの値として %SOAP.Fault12.Code を使用します。%SOAP.Fault12.Code クラスには以下のプロパティがあります。
Subcode
オプションのサブコードです。
Value
指定する値は、サブコードを指定したかどうかによって異なります。
%SOAP.Fault12.Text のプロパティ
%SOAP.Fault12 のインスタンスの Reason プロパティのリスト要素として、%SOAP.Fault12.Text を使用します。%SOAP.Fault12.Text クラスには以下のプロパティがあります。
Text
ユーザが確認できるように、フォルトの理由を示す文字列。
lang
フォルト・テキストが表されている言語または局所性に対応するコード。詳細は、W3 の Web サイト (http://www.w3.org/) を参照してください。
フォルト発生時の WS-Addressing ヘッダ要素の追加
フォルトの発生時に WS-Addressing ヘッダ要素を追加するように Caché Web サービスを設定できます。そのためには、Web サービスのフォルト処理に次の手順を追加します。
  1. フォルト発生時に使用するフォルトの宛先とフォルトのアクションを選択します。
  2. これらを引数として使用して、%SOAP.Addressing.Properties クラスの GetDefaultResponseProperties() メソッドを呼び出します。このメソッドからは、一般に必要となる値が設定された %SOAP.Addressing.Properties のインスタンスが返ります。
  3. 必要に応じて、%SOAP.Addressing.Properties のインスタンスのその他のプロパティを設定します。
    詳細は、%SOAP.Addressing.Properties のクラス・ドキュメントを参照してください。
  4. Web サービスの FaultAddressing プロパティを %SOAP.Addressing.Properties のインスタンスと等しくなるように設定します。
フォルト発生時のその他のヘッダ要素の追加
フォルト発生時にカスタムのヘッダ要素を追加するように Caché Web サービスを設定することもできます。このカスタムのヘッダ要素は、前のセクションで説明したオプションに追加するオプションとすることができるほか、それらのオプションに代わるものとすることもできます。以下はその方法です。
  1. %SOAP.Header のサブクラスを作成します。このサブクラスで、追加データを設定したプロパティを追加します。
    カスタム・ヘッダ要素の追加と使用 の章を参照してください。
  2. この章で既に取り上げた Web サービスのフォルト処理に次の手順を追加します。
    1. ヘッダ・サブクラスのインスタンスを作成します。
      注意:
      このようなクラス名になっていても、このオブジェクトはヘッダ全体を表しているわけではなく、実際には SOAP ヘッダ要素です。個々の SOAP メッセージには、複数の要素で構成したヘッダが 1 つあります。
    2. 必要に応じて、そのプロパティを設定します。
    3. 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='http://schemas.xmlsoap.org/soap/envelope/' 
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
xmlns:s='http://www.w3.org/2001/XMLSchema' xmlns:flt="http://myfault.org" >
  <SOAP-ENV:Header>
<CustomHeaderElement xmlns:hdr="http://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>
...
ここでは、見やすくするために改行を追加してあります。
Caché Web クライアントでの SOAP フォルトおよびその他のエラーの処理
Caché Web クライアントでは、TRY-CATCH メカニズム、または従来の $ZTRAP メカニズムを使用できます。
どちらの場合も、Caché Web クライアントがエラーを受信すると、特殊変数 $ZERROR%objlasterror が Caché で次のように設定されます。
例 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($$$CacheError,$ZERROR)
        }
    }
    
    Quit ans
}
このメソッドでは、%systemInclude インクルード・ファイルで定義されているシステム・マクロを使用しているため、このメソッドを含むクラスの先頭は以下のようになります。
Include %systemInclude 
例 2 : $ZTRAP
次の例では、従来の $ZTRAP メカニズムを使用しています。この場合、Caché 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 ハンドシェイクのエラー
Caché Web クライアントが SSL 接続を使用しているときに SSL ハンドシェイク・エラーが発生した場合、クライアントの SSLError プロパティにその SSL エラーを説明するテキストが格納されます。