startover / pythonfutures

Automatically exported from code.google.com/p/pythonfutures
Other
0 stars 0 forks source link

Implement exception-chaining for future.result() #2

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Chained exceptions are vital in debugging programs that use this library.

They are going to be added to py3k with
http://www.python.org/dev/peps/pep-3134/ but for people using python 2,
I've attached a quick-and-dirty implementation that is specific to
python-futures.

I've tested it for ThreadPoolExecutor but not ProcessPoolExecutor.

Sample output when future.result() is called:

Traceback (most recent call last):
  File "src/scrape.py", line 287, in <module>
    sys.exit(main(*args, **opts.__dict__))
  File "src/scrape.py", line 65, in main
    ret = f(*args)
  File "src/scrape.py", line 187, in round_photo
    self.ff.commitUserPhotos(socgr.vs["id"], ppdb)
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/tags/scrape/flic
kr.py",
line 265, in commitUserPhotos
    self.execAllUnique(users, ppdb, "producer db (user)", run, post, conc_m)
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/tags/scrape/flic
kr.py",
line 217, in execAllUnique
    LOG.info, "%s: %%(i1)s/%s %%(it)s" % (name, total), expected_length=total):
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/tags/scrape/util
.py",
line 188, in enumerate_cb
    for i, item in enumerate(iterable):
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/futures/_base.py
",
line 602, in run_to_results
    raise e
futures._base.ExecutionException: Caused by:
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/futures/thread.p
y",
line 87, in run
    result = self.call()
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/tags/scrape/flic
kr.py",
line 210, in <lambda>
    tasks = [partial(lambda it: (it, run(it)), it) for it in items if it
not in done]
  File
"/home/infinity0/0/work/compsci/ii-2009-project/tag-routing/src/tags/scrape/flic
kr.py",
line 253, in run
    print a[3]
IndexError('list index out of range',)

Original issue reported on code.google.com by infinity0x@gmail.com on 3 Apr 2010 at 6:29

Attachments:

GoogleCodeExporter commented 9 years ago
whoops, a minor fix to the patch:

in Future.__repr__, it should use "self._exc_info[0].__name__" instead of
"self._exc_info[0]"

also, you might want to implement a Future.exc_info() that does exactly the same
thing as Future.exception() but returns the whole of self._exc_info instead of 
just
self._exc_info[1].

Original comment by infinity0x@gmail.com on 3 Apr 2010 at 6:34

GoogleCodeExporter commented 9 years ago
The problem with this approach is that changes the exception type.

Original comment by brian.qu...@gmail.com on 30 Apr 2010 at 4:27

GoogleCodeExporter commented 9 years ago
This issue is solved in Python 3.x. Since that is what my PEP is targeting, 
maybe that is OK.

Original comment by brian.qu...@gmail.com on 30 Apr 2010 at 4:37

GoogleCodeExporter commented 9 years ago
if by "change the exception type" you mean it's now wrapped in another 
exception, why
is this a problem? it's what java does, and this library claims to be 
java-style?

Original comment by infinity0x@gmail.com on 12 May 2010 at 5:26

GoogleCodeExporter commented 9 years ago
Java has to do it because exceptions are checked - Python doesn't have that 
problem. Changing the 
exception type is annoying because it converts code that looks like this:

try:
  future.result()
except ValueError:
  ...
except IOError:
  ...

to:

try:
  future.result()
except futures.ExecutionException as e:
  if e.exc_info()[0] == ValueError:
     ...
  elif e.exc_info()[0] == IOError:
     ...

Original comment by Dublin...@gmail.com on 21 May 2010 at 1:18

GoogleCodeExporter commented 9 years ago
or just 

try:
  future.result()
except ExecutionException as e:
  try:
    raise e.exc_info()
  catch ValueError:
    ...
  catch IOError:
    ...

in which case the stack trace is preserved. your current way will destroy the 
stack
trace from when the exception was thrown in the other thread.

Original comment by infinity0x@gmail.com on 21 May 2010 at 8:52

GoogleCodeExporter commented 9 years ago

Original comment by brian.qu...@gmail.com on 14 Nov 2010 at 3:49