Show More
@@ -232,6 +232,8 b' class TaskRejectError(KernelError):' | |||||
232 |
|
232 | |||
233 | class CompositeError(RemoteError): |
|
233 | class CompositeError(RemoteError): | |
234 | """Error for representing possibly multiple errors on engines""" |
|
234 | """Error for representing possibly multiple errors on engines""" | |
|
235 | tb_limit = 4 # limit on how many tracebacks to draw | |||
|
236 | ||||
235 | def __init__(self, message, elist): |
|
237 | def __init__(self, message, elist): | |
236 | Exception.__init__(self, *(message, elist)) |
|
238 | Exception.__init__(self, *(message, elist)) | |
237 | # Don't use pack_exception because it will conflict with the .message |
|
239 | # Don't use pack_exception because it will conflict with the .message | |
@@ -256,9 +258,11 b' class CompositeError(RemoteError):' | |||||
256 |
|
258 | |||
257 | def __str__(self): |
|
259 | def __str__(self): | |
258 | s = str(self.msg) |
|
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 | engine_str = self._get_engine_str(ei) |
|
262 | engine_str = self._get_engine_str(ei) | |
261 | s = s + '\n' + engine_str + en + ': ' + str(ev) |
|
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 | return s |
|
266 | return s | |
263 |
|
267 | |||
264 | def __repr__(self): |
|
268 | def __repr__(self): | |
@@ -268,10 +272,14 b' class CompositeError(RemoteError):' | |||||
268 | """render one or all of my tracebacks to a list of lines""" |
|
272 | """render one or all of my tracebacks to a list of lines""" | |
269 | lines = [] |
|
273 | lines = [] | |
270 | if excid is None: |
|
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 | lines.append(self._get_engine_str(ei)) |
|
276 | lines.append(self._get_engine_str(ei)) | |
273 | lines.extend((etb or 'No traceback available').splitlines()) |
|
277 | lines.extend((etb or 'No traceback available').splitlines()) | |
274 | lines.append('') |
|
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 | else: |
|
283 | else: | |
276 | try: |
|
284 | try: | |
277 | en,ev,etb,ei = self.elist[excid] |
|
285 | en,ev,etb,ei = self.elist[excid] |
@@ -619,6 +619,33 b' class TestView(ClusterTestCase, ParametricTestCase):' | |||||
619 | self.assertEqual(io.stdout.count('by zero'), len(view), io.stdout) |
|
619 | self.assertEqual(io.stdout.count('by zero'), len(view), io.stdout) | |
620 | self.assertEqual(io.stdout.count(':execute'), len(view), io.stdout) |
|
620 | self.assertEqual(io.stdout.count(':execute'), len(view), io.stdout) | |
621 |
|
621 | |||
|
622 | def test_compositeerror_truncate(self): | |||
|
623 | """Truncate CompositeErrors with many exceptions""" | |||
|
624 | view = self.client[:] | |||
|
625 | msg_ids = [] | |||
|
626 | for i in range(10): | |||
|
627 | ar = view.execute("1/0") | |||
|
628 | msg_ids.extend(ar.msg_ids) | |||
|
629 | ||||
|
630 | ar = self.client.get_result(msg_ids) | |||
|
631 | try: | |||
|
632 | ar.get() | |||
|
633 | except error.CompositeError as e: | |||
|
634 | pass | |||
|
635 | else: | |||
|
636 | self.fail("Should have raised CompositeError") | |||
|
637 | ||||
|
638 | lines = e.render_traceback() | |||
|
639 | with capture_output() as io: | |||
|
640 | e.print_traceback() | |||
|
641 | ||||
|
642 | self.assertTrue("more exceptions" in lines[-1]) | |||
|
643 | count = e.tb_limit | |||
|
644 | ||||
|
645 | self.assertEqual(io.stdout.count('ZeroDivisionError'), 2 * count, io.stdout) | |||
|
646 | self.assertEqual(io.stdout.count('by zero'), count, io.stdout) | |||
|
647 | self.assertEqual(io.stdout.count(':execute'), count, io.stdout) | |||
|
648 | ||||
622 | @dec.skipif_not_matplotlib |
|
649 | @dec.skipif_not_matplotlib | |
623 | def test_magic_pylab(self): |
|
650 | def test_magic_pylab(self): | |
624 | """%pylab works on engines""" |
|
651 | """%pylab works on engines""" |
General Comments 0
You need to be logged in to leave comments.
Login now