##// END OF EJS Templates
Merge pull request #2871 from minrk/shortexc...
Brian E. Granger -
r9725:c2bc10dd merge
parent child Browse files
Show More
@@ -232,6 +232,8 b' class TaskRejectError(KernelError):'
232 232
233 233 class CompositeError(RemoteError):
234 234 """Error for representing possibly multiple errors on engines"""
235 tb_limit = 4 # limit on how many tracebacks to draw
236
235 237 def __init__(self, message, elist):
236 238 Exception.__init__(self, *(message, elist))
237 239 # Don't use pack_exception because it will conflict with the .message
@@ -256,22 +258,28 b' class CompositeError(RemoteError):'
256 258
257 259 def __str__(self):
258 260 s = str(self.msg)
259 for en, ev, etb, ei in self.elist:
261 for en, ev, etb, ei in self.elist[:self.tb_limit]:
260 262 engine_str = self._get_engine_str(ei)
261 263 s = s + '\n' + engine_str + en + ': ' + str(ev)
264 if len(self.elist) > self.tb_limit:
265 s = s + '\n.... %i more exceptions ...' % (len(self.elist) - self.tb_limit)
262 266 return s
263 267
264 268 def __repr__(self):
265 return "CompositeError(%i)"%len(self.elist)
269 return "CompositeError(%i)" % len(self.elist)
266 270
267 271 def render_traceback(self, excid=None):
268 272 """render one or all of my tracebacks to a list of lines"""
269 273 lines = []
270 274 if excid is None:
271 for (en,ev,etb,ei) in self.elist:
275 for (en,ev,etb,ei) in self.elist[:self.tb_limit]:
272 276 lines.append(self._get_engine_str(ei))
273 277 lines.extend((etb or 'No traceback available').splitlines())
274 278 lines.append('')
279 if len(self.elist) > self.tb_limit:
280 lines.append(
281 '... %i more exceptions ...' % (len(self.elist) - self.tb_limit)
282 )
275 283 else:
276 284 try:
277 285 en,ev,etb,ei = self.elist[excid]
@@ -622,6 +622,33 b' class TestView(ClusterTestCase, ParametricTestCase):'
622 622 self.assertEqual(io.stdout.count('by zero'), len(view), io.stdout)
623 623 self.assertEqual(io.stdout.count(':execute'), len(view), io.stdout)
624 624
625 def test_compositeerror_truncate(self):
626 """Truncate CompositeErrors with many exceptions"""
627 view = self.client[:]
628 msg_ids = []
629 for i in range(10):
630 ar = view.execute("1/0")
631 msg_ids.extend(ar.msg_ids)
632
633 ar = self.client.get_result(msg_ids)
634 try:
635 ar.get()
636 except error.CompositeError as e:
637 pass
638 else:
639 self.fail("Should have raised CompositeError")
640
641 lines = e.render_traceback()
642 with capture_output() as io:
643 e.print_traceback()
644
645 self.assertTrue("more exceptions" in lines[-1])
646 count = e.tb_limit
647
648 self.assertEqual(io.stdout.count('ZeroDivisionError'), 2 * count, io.stdout)
649 self.assertEqual(io.stdout.count('by zero'), count, io.stdout)
650 self.assertEqual(io.stdout.count(':execute'), count, io.stdout)
651
625 652 @dec.skipif_not_matplotlib
626 653 def test_magic_pylab(self):
627 654 """%pylab works on engines"""
@@ -560,25 +560,25 b' more other types of exceptions. Here is how it works:'
560 560 In [79]: dview.execute("1/0")
561 561 [0:execute]:
562 562 ---------------------------------------------------------------------------
563 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
563 ZeroDivisionError Traceback (most recent call last)
564 564 ----> 1 1/0
565 565 ZeroDivisionError: integer division or modulo by zero
566 566
567 567 [1:execute]:
568 568 ---------------------------------------------------------------------------
569 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
569 ZeroDivisionError Traceback (most recent call last)
570 570 ----> 1 1/0
571 571 ZeroDivisionError: integer division or modulo by zero
572 572
573 573 [2:execute]:
574 574 ---------------------------------------------------------------------------
575 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
575 ZeroDivisionError Traceback (most recent call last)
576 576 ----> 1 1/0
577 577 ZeroDivisionError: integer division or modulo by zero
578 578
579 579 [3:execute]:
580 580 ---------------------------------------------------------------------------
581 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
581 ZeroDivisionError Traceback (most recent call last)
582 582 ----> 1 1/0
583 583 ZeroDivisionError: integer division or modulo by zero
584 584
@@ -595,7 +595,7 b' If you want, you can even raise one of these original exceptions:'
595 595 ....:
596 596 ....:
597 597 ---------------------------------------------------------------------------
598 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
598 ZeroDivisionError Traceback (most recent call last)
599 599 ----> 1 1/0
600 600 ZeroDivisionError: integer division or modulo by zero
601 601
@@ -608,25 +608,25 b' instance:'
608 608 In [81]: dview.execute('1/0')
609 609 [0:execute]:
610 610 ---------------------------------------------------------------------------
611 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
611 ZeroDivisionError Traceback (most recent call last)
612 612 ----> 1 1/0
613 613 ZeroDivisionError: integer division or modulo by zero
614 614
615 615 [1:execute]:
616 616 ---------------------------------------------------------------------------
617 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
617 ZeroDivisionError Traceback (most recent call last)
618 618 ----> 1 1/0
619 619 ZeroDivisionError: integer division or modulo by zero
620 620
621 621 [2:execute]:
622 622 ---------------------------------------------------------------------------
623 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
623 ZeroDivisionError Traceback (most recent call last)
624 624 ----> 1 1/0
625 625 ZeroDivisionError: integer division or modulo by zero
626 626
627 627 [3:execute]:
628 628 ---------------------------------------------------------------------------
629 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
629 ZeroDivisionError Traceback (most recent call last)
630 630 ----> 1 1/0
631 631 ZeroDivisionError: integer division or modulo by zero
632 632
@@ -654,11 +654,31 b' instance:'
654 654 ipdb> e.print_traceback(1)
655 655 [1:execute]:
656 656 ---------------------------------------------------------------------------
657 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
657 ZeroDivisionError Traceback (most recent call last)
658 658 ----> 1 1/0
659 659 ZeroDivisionError: integer division or modulo by zero
660 660
661 661
662 Since you might have 100 engines, you probably don't want to see 100 tracebacks
663 for a simple NameError because of a typo.
664 For this reason, CompositeError truncates the list of exceptions it will print
665 to :attr:`CompositeError.tb_limit` (default is five).
666 You can change this limit to suit your needs with:
667
668 .. sourcecode:: ipython
669
670 In [20]: from IPython.parallel import CompositeError
671 In [21]: CompositeError.tb_limit = 1
672 In [22]: %px a=b
673 [0:execute]:
674 ---------------------------------------------------------------------------
675 NameError Traceback (most recent call last)
676 ----> 1 a=b
677 NameError: name 'b' is not defined
678
679 ... 3 more exceptions ...
680
681
662 682 All of this same error handling magic even works in non-blocking mode:
663 683
664 684 .. sourcecode:: ipython
@@ -670,25 +690,8 b' All of this same error handling magic even works in non-blocking mode:'
670 690 In [85]: ar.get()
671 691 [0:execute]:
672 692 ---------------------------------------------------------------------------
673 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
674 ----> 1 1/0
675 ZeroDivisionError: integer division or modulo by zero
676
677 [1:execute]:
678 ---------------------------------------------------------------------------
679 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
693 ZeroDivisionError Traceback (most recent call last)
680 694 ----> 1 1/0
681 695 ZeroDivisionError: integer division or modulo by zero
682
683 [2:execute]:
684 ---------------------------------------------------------------------------
685 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
686 ----> 1 1/0
687 ZeroDivisionError: integer division or modulo by zero
688
689 [3:execute]:
690 ---------------------------------------------------------------------------
691 ZeroDivisionError Traceback (most recent call last)<ipython-input-1-05c9758a9c21> in <module>()
692 ----> 1 1/0
693 ZeroDivisionError: integer division or modulo by zero
694
696
697 ... 3 more exceptions ...
General Comments 0
You need to be logged in to leave comments. Login now