記事
· 2 hr 前 6m read

Embedded Python利用時にエラーが発生した場合の対応方法のご紹介

これは InterSystems FAQ サイトの記事です。

PythonスクリプトファイルやPythonで記述されたIRIS内メソッドを呼び出す際、エラーが発生した場合の対応方法をご紹介します。

説明使用するコードや資料PDFは公開しています👉 test1.pyFS.Utilsクラスコードのコピー元ビデオで解説している資料PDF

Embedded Python 自習用ビデオをご用意しています(項目別にYouTubeプレイリストをご用意しています)。

各プレイリストについて詳しくはこちらをご参照ください👉【はじめてのInterSystems IRIS】Embedded Python セルフラーニングビデオシリーズ公開!

Python側でエラーが発生した場合、ObjectScriptのシステムエラーとして取り扱うことができます。

具体的に確認してみましょう。

解説と実行例については以下のビデオの 最初~03:57までで解説しています。

https://www.youtube.com/embed/GXeQgy1IIE0?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

例えば、以下メソッドの第2引数に0を指定すると'ZeroDivisionError'エラーが発生します。IRISから呼び出した場合は、このエラーは特殊変数$ZERRORにセットされます(=ObjectScriptでエラーが発生したときと同じ状況になります)

ClassMethod errtest1(a As %Integer, b As %Integer) As %Integer [ Language = python ]
{
    result=a/b
    return result
}

 

IRISから実行した場合の結果は以下の通りです(特殊変数$ZERRORにエラー文字列が設定されていることを確認できます)。

USER>do ##class(FS.Utils).errtest1(1,0) DO ##CLASS(FS.Utils).errtest1(1,0)
^
<THROW> *%Exception.PythonException  230 ^^0^ <class 'ZeroDivisionError'>: division by zero -
USER> USER>write $ZE
<THROW> *%Exception.PythonException  230 ^^0^ <class 'ZeroDivisionError'>: division by zero -
USER>

 

次に、Pythonのコード内で%Statusのエラーが発生した場合はどうなるでしょうか。

https://www.youtube.com/embed/GXeQgy1IIE0?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=237
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

下記コードの解説と実行例については、ビデオの 03:37~ 07:43まで解説しています。

《ObjectScript》

ClassMethod statustest() [ Language = python ]
{
    import iris
    try:
        a=iris.cls("FS.Person")._New()
        a.DOB="ThisIsError"
        st=a._Save()
        iris.check_status(st)
    except RuntimeError as ex:
        print("pythonのエクセプション!")
        print(str(repr(ex)))
        raise
}

《ターミナル実行例》

write ##class(FS.Utils).errtest1(1,0)

 

《Pythonスクリプト》

def err1(a,b):
    result=a/b
    return result

《ターミナルでの実行例》

set sys=##class(%SYS.Python).Import("sys")
do sys.path.append("c:\WorkSpace\TryIRIS")
set test1=##class(%SYS.Python).Import("test1")
write test1.err1(1,0)

 

SQL実行時のエラーはどうなるでしょうか。

https://www.youtube.com/embed/GXeQgy1IIE0?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=463
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

下記コードの解説と実行例については、ビデオの07:43~09:06 をご参照ください。

《Pythonスクリプト》

def sqlerr():
    import iris
    import irisbuiltins
    try:
        sql="select * from Training.Person"
        rset=iris.sql.exec(sql)
        for key,val in enumerate(rset):
            print(val)

    except irisbuiltins.SQLError as ex:
        print(str(repr(ex)))
        print(ex.sqlcode)
        print(ex.message)
        print(ex.statement)
        raise

《IRISのターミナルでの実行例》

//システムエラーが発生した場合に$ZE特殊変数に情報が設定されます
write $ZE
// Pythonシェル起動
do ##class(%SYS.Python).Shell()
## 以下Pythonシェルで実行
import sys
sys.path+=["c:\WorkSpace\TryIRIS"]
import test1
test1.sqlerr()
quit()
// 以下IRISターミナルで実行
write $ZE 

 

Python側でエラー処理を書かない場合の説明についてはビデオ 09:06~ ご参照ください。

https://www.youtube.com/embed/GXeQgy1IIE0?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=547
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]


 

続いて、Embedded Python利用時にエラーが発生した場合のエラー処理例をご紹介します。

戻り値でエラーだったことを報告する例(Pythonスクリプトの例)の解説は、ビデオの最初~1:48までをご参照ください。

https://www.youtube.com/embed/sX3UBtTH9mA?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

 

戻り値でエラーだったことを報告する例(language=pythonの例)は、以下ビデオの1:48~3:16で解説しています。

https://www.youtube.com/embed/sX3UBtTH9mA?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=108
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

コード例は以下の通りです。

《Pythonスクリプト》

def err2(a,b):
    try:
        if b==1:
            modori="1で割っても答えは同じです"
            return modori
        print(f"割り算の答えは={a/b}")
        modori="OK"
        return modori
    except ZeroDivisionError as ex:
        modori=str(repr(ex))
        print(modori)
        return modori

《IRISからの実行例》

set sys=##class(%SYS.Python).Import("sys")
do sys.path.append("C:\WorkSpace\TryIRIS")
set errtest=##class(%SYS.Python).Import("test1")
set ret=errtest.err2(2,2) write ret
set ret=errtest.err2(2,1)
write ret
set ret=errtest.err2(2,0)
write ret

 

《ObjectScriptの例》

ClassMethod errtest2(a As %Integer, b As %Integer) As %Integer [ Language = python ]
{
    try:
        if b==1:
            modori="1で割っても答えは同じです"
            return modori
        print(f"割り算の答えは={a/b}")
        modori="OK"
        return modori
    except ZeroDivisionError as ex:
        modori=str(repr(ex))
        print(modori)
        return modori
}

《ターミナル実行例》

set modori=##class(FS.Utils).errtest2(2,2)
write modori
set modori=##class(FS.Utils).errtest2(2,1)
write modori
set modori=##class(FS.Utils).errtest2(2,0)
write modori

 

戻り値でエラーだったことを報告する例(%Statusを戻す場合)は、ビデオの3:38~5:22で解説しています。

https://www.youtube.com/embed/sX3UBtTH9mA?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=219
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

コード例は以下の通りです。

《ObjectScriptの例》

ClassMethod errtest3(a As %Integer, b As %Integer) As %Status [ Language = python ]
{
    import iris
    try:
        print(a/b)
        ret=1
    except Exception as ex:
        moji="エラーが発生しました!"+str(repr(ex))
        ret=iris.system.Status.Error(5001,moji)
    return ret
}

《ターミナル実行例》

set status=##class(FS.Utils).errtest3(1,0)
write $system.Status.GetErrorText(status)
set status=##class(FS.Utils).errtest3(1,1)
write status

 

try: except: を使う + raise でそのままIRISに例外を戻す例と解説は以下ビデオ5:22~最後までご覧ください。

https://www.youtube.com/embed/sX3UBtTH9mA?list=PLzSN_5VbNaxBLXlC9oCgwPtxBilT8tJ96&start=322
[これは埋め込みリンクですが、あなたはサイト上の埋め込みコンテンツへのアクセスに必要な Cookie を拒否しているため、それを直接表示することはできません。埋め込みコンテンツを表示するには、Cookie 設定ですべての Cookie を受け入れる必要があります。]

《Pythonスクリプトの例》

def err3(a,b):
    try:
        ret=a/b
        print(ret)
    except:
        raise

《ObjectScriptコード例》

ClassMethod errtest4() As %Status
{
    #dim ex As %Exception.AbstractException
    try {
        set sys=##class(%SYS.Python).Import("sys")
        do sys.path.append("C:\WorkSpace\TryIRIS")
        set errtest=##class(%SYS.Python).Import("test1")
        do errtest.err3(1,0)
    }
    catch ex {
        write "エラーが発生しました:",ex.DisplayString(),!
        //例外から%Statusに変換
        set st=ex.AsStatus()
        //例外からSQLCODEとメッセージを取得
        set SQLCODE=ex.AsSQLCODE()
        set SQLMessage=ex.AsSQLMessage()
    }
} 

《ターミナル実行例》

do ##class(FS.Utils).errtest4()
ディスカッション (0)1
続けるにはログインするか新規登録を行ってください