python3如何在应用error_callback时找出apply_async目标函数中的哪一行导致错误

时间:2015-02-18 22:30:31

标签: python python-3.x multiprocessing python-multiprocessing

使用python 3.4

我有一个失败的目标函数,apply_async调用我的错误回调函数而不是我的回调函数。

问题是捕获并发送到error_callback的异常没有用,我无法弄清楚 目标函数中的错误

我的错误回调

  def error_callback(self,e):
    print('error_callback()',e)
    # tested one of these at a time
    traceback.print_exc()
    traceback.print_last()
    traceback.print_stack()

追溯输出

print_exc

  File "/usr/lib/python3.4/traceback.py", line 125, in _iter_chain
    context = exc.__context__
  AttributeError: 'NoneType' object has no attribute '__context__'

print_last

  File "/usr/lib/python3.4/traceback.py", line 262, in print_last
    raise ValueError("no last exception")
  ValueError: no last exception

print_stack

  File "./relative/path/to/my/script.py", line 71, in traceback
    traceback.print_stack()

我必须承认我对跟踪库以及如何使用它感到非常自在,但在我看来,在这种情况下它不可能使用回溯吗? / p>

我该怎么办?

2 个答案:

答案 0 :(得分:2)

您正在调用的traceback函数都希望从sys.exec_info获取异常信息,这是异常信息通常在捕获异常时存储的位置。但是,由于您的案例中的实际异常来自子进程,因此他们在父进程中找不到任何异常信息。

您需要使用从子进程收到的异常对象e中提取相关信息。尝试使用traceback.print_exception和适当的参数:

traceback.print_exception(type(e), e, e.__traceback__)

答案 1 :(得分:2)

  

我无法弄清楚目标函数中的错误发生在哪里。

以下是您可以执行的操作示例:

import multiprocessing as mp

def do_stuff(num):
    if False:
        x = 10
    else: 
        x = 20

    result = 5/(2 - num)  #Line 9
    return result 

def success_handler(result):
    print('success')

def error_handler(e):
    print('error')
    print(dir(e), "\n")
    print("-->{}<--".format(e.__cause__))

with mp.Pool(2) as my_pool:
    results =  [
        my_pool.apply_async(
            do_stuff, 
            args=(i,),
            callback=success_handler, 
            error_callback=error_handler
       ) 
       for i in range(3)
    ]


    try:
        for result_obj in results:
            print("result is: {}".format(result_obj.get()))
    except ZeroDivisionError as e:
        print("Oh, boy.  This is the second time I've seen this error.")


--output:--
success
success
result is: 2.5
result is: 5.0
error
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback'] 

-->
"""
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
  File "1.py", line 10, in do_stuff
    result = 5/(2 - num)  #Line 9
ZeroDivisionError: division by zero
"""<--
Oh, boy.  This is the second time I've seen this error.

请注意错误消息中目标函数的行号。

我真的不明白error_callback的目的,因为在调用error_callback之后,多处理会重新引发错误,所以无论如何你必须抓住它。我想error_calback必须用于进行特定于进程的清理。