简体   繁体   English

Python Execnet和异常处理

[英]Python Execnet and Exception Handling

I am using execnet to call a jython module from within a python script. 我正在使用execnet从python脚本中调用jython模块。

From the docs : 文档

Note that exceptions from the remotely executing code will be reraised as channel.RemoteError exceptions containing a textual representation of the remote traceback. 请注意,来自远程执行代码的异常将重新引发为channel.RemoteError异常,其中包含远程回溯的文本表示形式。

Let's say my remote module could result in two different exceptions, and I would like to be able to handle each exception differently. 假设我的远程模块可能导致两个不同的异常,而我希望能够以不同的方式处理每个异常。 How will I be able to handle this, given that both exceptions will instead throw a RemoteError exception that only contains a string of the traceback? 考虑到这两个异常都将引发一个RemoteError异常,该异常仅包含一个追溯字符串,我将如何处理呢?

For example, this particular calling code: 例如,此特定的调用代码:

#...
channel.send('bogus')

results in the following RemoteError , which just contains an attribute formatted that contains a string of the traceback: 导致以下RemoteError ,其中仅包含formatted的属性,该属性的formatted包含回溯字符串:

RemoteError: Traceback (most recent call last):
  File "<string>", line 1072, in executetask
  File "<string>", line 1, in do_exec
  File "<remote exec>", line 33, in <module>
IOError: Open failed for table: bogus, error: No such file or directory (2)

I cannot do a try ... except IOError: . 我无法try ... except IOError: I could do a try ... except RemoteError as ex: and parse the ex.formatted to see if it contains IOError , and then raise that instead, but this seems rather sloppy: 我可以try ... except RemoteError as ex:然后解析ex.formatted来查看它是否包含IOError ,然后引发该错误,但这似乎很草率:

from execnet.gateway_base import RemoteError
try:
    channel.send('bogus')
except RemoteError as ex:
    if 'IOError' in ex.formatted:
        raise IOError(ex.formatted[ex.formatted.find('IOError'): -1])
    if 'ValueError' in ex.formatted:
        raise ValueError(ex.formatted[ex.formatted.find('ValueError'): -1])
    # otherwise, reraise the uncaptured error:
    raise ex

An old question - I tried to answer it 一个老问题-我试图回答

import unittest
from execnet.gateway_base import RemoteError
import execnet

class Test(unittest.TestCase):

    def RemoteErrorHandler(self,error):
        e,t = error.formatted.splitlines()[-1].split(':')
        raise getattr(__builtins__,e)(t)

    def raising_receive(self, ch):
        try:
            return ch.receive()
        except RemoteError as ex:
            self.RemoteErrorHandler(ex)

    def setUp(self):
        self.gateway = execnet.makegateway()


    def test_NameError(self):
        ch = self.gateway.remote_exec("print o")
        with self.assertRaises(NameError):
            self.raising_receive(ch)


if __name__ == '__main__':
    unittest.main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM