Submitter | Matt Harbison |
---|---|
Date | Feb. 9, 2013, 6:06 a.m. |
Message ID | <1744b3545df41d6202a0.1360390004@Envy> |
Download | mbox | patch |
Permalink | /patch/853/ |
State | Superseded, archived |
Headers | show |
Comments
On 02/09/2013 07:06 AM, Matt Harbison wrote: > # HG changeset patch > # User Matt Harbison <matt_harbison@yahoo.com> > # Date 1360388586 18000 > # Branch stable > # Node ID 1744b3545df41d6202a0f0857a17d1053ad44b71 > # Parent 8b82d3b7f96e76877e0f3babf7a27b42791ab949 > ui: add support for fully printing chained exception tracebacks I think it is worth mentioning that it is a change to ui.traceback(). > Currently, only SubrepoAbort has a cause chained to it. > > diff --git a/mercurial/ui.py b/mercurial/ui.py > --- a/mercurial/ui.py > +++ b/mercurial/ui.py > @@ -686,11 +686,23 @@ > only to call in exception handler. returns true if traceback > printed.''' > if self.tracebackflag: > - if exc: > + if exc is None: > + exc = sys.exc_info() > + cause = getattr(exc[1], 'cause', None) > + > + if cause is not None: > + causetb = traceback.format_tb(cause[2]) > + exctb = traceback.format_tb(exc[2]) > + exconly = traceback.format_exception_only(cause[0], cause[1]) > + > + # exclude frame where 'exc' was chained and rethrown from exctb > + self.write_err('Traceback (most recent call last):\n', > + ''.join(exctb[:-1]), > + ''.join(causetb), > + ''.join(exconly)) > + else: > traceback.print_exception(exc[0], exc[1], exc[2], > file=self.ferr) > - else: > - traceback.print_exc(file=self.ferr) > return self.tracebackflag > > def geteditor(self): > diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t > --- a/tests/test-subrepo.t > +++ b/tests/test-subrepo.t > @@ -644,7 +644,43 @@ > adding file changes > added 2 changesets with 3 changes to 2 files > (run 'hg update' to get a working copy) > - $ hg -R issue1852b update > + $ hg -R issue1852b update --traceback > + Traceback (most recent call last): > + File "*/mercurial/dispatch.py", line *, in _runcatch (glob) > + return _dispatch(req) > + File "*/mercurial/dispatch.py", line *, in _dispatch (glob) > + cmdpats, cmdoptions) > + File "*/mercurial/dispatch.py", line *, in runcommand (glob) > + ret = _runcommand(ui, options, cmd, d) > + File "*/mercurial/dispatch.py", line *, in _runcommand (glob) > + return checkargs() > + File "*/mercurial/dispatch.py", line *, in checkargs (glob) > + return cmdfunc() > + File "*/mercurial/dispatch.py", line *, in <lambda> (glob) > + d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) > + File "*/mercurial/util.py", line *, in check (glob) > + return func(*args, **kwargs) > + File "*/mercurial/commands.py", line *, in update (glob) > + ret = hg.update(repo, rev) > + File "*/mercurial/hg.py", line *, in update (glob) > + stats = updaterepo(repo, node, False) > + File "*/mercurial/hg.py", line *, in updaterepo (glob) > + return mergemod.update(repo, node, False, overwrite, None) > + File "*/mercurial/merge.py", line *, in update (glob) > + stats = applyupdates(repo, actions, wc, p2, pa, overwrite) > + File "*/mercurial/merge.py", line *, in applyupdates (glob) > + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) > + File "*/mercurial/subrepo.py", line *, in submerge (glob) > + mctx.sub(s).get(r) > + File "*/mercurial/subrepo.py", line *, in decoratedmethod (glob) > + res = func(self, *args, **kargs) > + File "*/mercurial/subrepo.py", line *, in get (glob) > + self._get(state) > + File "*/mercurial/subrepo.py", line *, in _get (glob) > + srcurl = _abssource(self._repo) > + File "*/mercurial/subrepo.py", line *, in _abssource (glob) > + raise util.Abort(_("default path for subrepository not found")) > + Abort: default path for subrepository not found > abort: default path for subrepository not found (in subrepo sub/repo) (glob) > [255] I don't know how stable the backtrace format is over Python versions - I wouldn't rely on it being stable. This test will also fail whenever the code path changes slightly. Instead I suggest grepping for an essential part of a single line. /Mads
Patch
diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -686,11 +686,23 @@ only to call in exception handler. returns true if traceback printed.''' if self.tracebackflag: - if exc: + if exc is None: + exc = sys.exc_info() + cause = getattr(exc[1], 'cause', None) + + if cause is not None: + causetb = traceback.format_tb(cause[2]) + exctb = traceback.format_tb(exc[2]) + exconly = traceback.format_exception_only(cause[0], cause[1]) + + # exclude frame where 'exc' was chained and rethrown from exctb + self.write_err('Traceback (most recent call last):\n', + ''.join(exctb[:-1]), + ''.join(causetb), + ''.join(exconly)) + else: traceback.print_exception(exc[0], exc[1], exc[2], file=self.ferr) - else: - traceback.print_exc(file=self.ferr) return self.tracebackflag def geteditor(self): diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -644,7 +644,43 @@ adding file changes added 2 changesets with 3 changes to 2 files (run 'hg update' to get a working copy) - $ hg -R issue1852b update + $ hg -R issue1852b update --traceback + Traceback (most recent call last): + File "*/mercurial/dispatch.py", line *, in _runcatch (glob) + return _dispatch(req) + File "*/mercurial/dispatch.py", line *, in _dispatch (glob) + cmdpats, cmdoptions) + File "*/mercurial/dispatch.py", line *, in runcommand (glob) + ret = _runcommand(ui, options, cmd, d) + File "*/mercurial/dispatch.py", line *, in _runcommand (glob) + return checkargs() + File "*/mercurial/dispatch.py", line *, in checkargs (glob) + return cmdfunc() + File "*/mercurial/dispatch.py", line *, in <lambda> (glob) + d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) + File "*/mercurial/util.py", line *, in check (glob) + return func(*args, **kwargs) + File "*/mercurial/commands.py", line *, in update (glob) + ret = hg.update(repo, rev) + File "*/mercurial/hg.py", line *, in update (glob) + stats = updaterepo(repo, node, False) + File "*/mercurial/hg.py", line *, in updaterepo (glob) + return mergemod.update(repo, node, False, overwrite, None) + File "*/mercurial/merge.py", line *, in update (glob) + stats = applyupdates(repo, actions, wc, p2, pa, overwrite) + File "*/mercurial/merge.py", line *, in applyupdates (glob) + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) + File "*/mercurial/subrepo.py", line *, in submerge (glob) + mctx.sub(s).get(r) + File "*/mercurial/subrepo.py", line *, in decoratedmethod (glob) + res = func(self, *args, **kargs) + File "*/mercurial/subrepo.py", line *, in get (glob) + self._get(state) + File "*/mercurial/subrepo.py", line *, in _get (glob) + srcurl = _abssource(self._repo) + File "*/mercurial/subrepo.py", line *, in _abssource (glob) + raise util.Abort(_("default path for subrepository not found")) + Abort: default path for subrepository not found abort: default path for subrepository not found (in subrepo sub/repo) (glob) [255]