Mercurial > hg-stable
changeset 23067:420a051616ce stable
bundle2: transmit exception during part generation
If an exception is raised during a bundle2 part payload generation it is now
recorded in the bundle. If such exception occurs, we capture it, transmit an
abort exception through the bundle, cleanly close the current part payload and
raise it again. This allow to generate valid bundle even in case of exception so
that the consumer does not wait forever for a dead producer. This also allow to
raise the exception during unbundling at the exact point it happened during
bundling make debugging easier.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Wed, 15 Oct 2014 03:52:20 -0700 |
parents | ad144882318d |
children | fb3e63c603e8 |
files | mercurial/bundle2.py tests/test-bundle2-format.t |
diffstat | 2 files changed, 19 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/bundle2.py Tue Oct 14 10:47:47 2014 -0700 +++ b/mercurial/bundle2.py Wed Oct 15 03:52:20 2014 -0700 @@ -145,6 +145,7 @@ preserve. """ +import sys import util import struct import urllib @@ -673,9 +674,22 @@ yield _pack(_fpartheadersize, len(headerchunk)) yield headerchunk ## payload - for chunk in self._payloadchunks(): - yield _pack(_fpayloadsize, len(chunk)) - yield chunk + try: + for chunk in self._payloadchunks(): + yield _pack(_fpayloadsize, len(chunk)) + yield chunk + except Exception, exc: + # backup exception data for later + exc_info = sys.exc_info() + msg = 'unexpected error: %s' % exc + interpart = bundlepart('b2x:error:abort', [('message', msg)]) + interpart.id = 0 + yield _pack(_fpayloadsize, -1) + for chunk in interpart.getchunks(): + yield chunk + # abort current part payload + yield _pack(_fpayloadsize, 0) + raise exc_info[0], exc_info[1], exc_info[2] # end of payload yield _pack(_fpayloadsize, 0) self._generated = True
--- a/tests/test-bundle2-format.t Tue Oct 14 10:47:47 2014 -0700 +++ b/tests/test-bundle2-format.t Wed Oct 15 03:52:20 2014 -0700 @@ -777,25 +777,22 @@ Check handling of exception during generation. ---------------------------------------------- -(is currently not right) $ hg bundle2 --genraise > ../genfailed.hg2 abort: Someone set up us the bomb! [255] Should still be a valid bundle -(is currently not right) $ cat ../genfailed.hg2 HG2Y\x00\x00\x00\x00\x00\x00\x00\x11 (esc) - b2x:output\x00\x00\x00\x00\x00\x00 (no-eol) (esc) + b2x:output\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00L\x0fb2x:error:abort\x00\x00\x00\x00\x01\x00\x07-messageunexpected error: Someone set up us the bomb!\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc) And its handling on the other size raise a clean exception -(is currently not right) $ cat ../genfailed.hg2 | hg unbundle2 0 unread bytes - abort: stream ended unexpectedly (got 0 bytes, expected 4) + abort: unexpected error: Someone set up us the bomb! [255]