diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -734,7 +734,7 @@ def overridecopy(orig, ui, repo, pats, o try: result = orig(ui, repo, pats, opts, rename) except error.Abort as e: - if pycompat.bytestr(e) != _(b'no files to copy'): + if e.message != _(b'no files to copy'): raise e else: nonormalfiles = True @@ -851,7 +851,7 @@ def overridecopy(orig, ui, repo, pats, o lfdirstate.add(destlfile) lfdirstate.write() except error.Abort as e: - if pycompat.bytestr(e) != _(b'no files to copy'): + if e.message != _(b'no files to copy'): raise e else: nolfiles = True diff --git a/hgext/narrow/narrowwirepeer.py b/hgext/narrow/narrowwirepeer.py --- a/hgext/narrow/narrowwirepeer.py +++ b/hgext/narrow/narrowwirepeer.py @@ -13,7 +13,6 @@ from mercurial import ( extensions, hg, narrowspec, - pycompat, wireprototypes, wireprotov1peer, wireprotov1server, @@ -125,7 +124,7 @@ def narrow_widen( ) except error.Abort as exc: bundler = bundle2.bundle20(repo.ui) - manargs = [(b'message', pycompat.bytestr(exc))] + manargs = [(b'message', exc.message)] advargs = [] if exc.hint is not None: advargs.append((b'hint', exc.hint)) diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -2089,7 +2089,7 @@ def handleremotechangegroup(op, inpart): except error.Abort as e: raise error.Abort( _(b'bundle at %s is corrupted:\n%s') - % (util.hidepassword(raw_url), bytes(e)) + % (util.hidepassword(raw_url), e.message) ) assert not inpart.read() diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py --- a/mercurial/chgserver.py +++ b/mercurial/chgserver.py @@ -502,7 +502,7 @@ class chgcmdserver(commandserver.server) self.cresult.write(b'exit 255') return except error.Abort as inst: - self.ui.error(_(b"abort: %s\n") % inst) + self.ui.error(_(b"abort: %s\n") % inst.message) if inst.hint: self.ui.error(_(b"(%s)\n") % inst.hint) self.ui.flush() diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py --- a/mercurial/commandserver.py +++ b/mercurial/commandserver.py @@ -500,7 +500,7 @@ def _serverequest(ui, repo, conn, create # handle exceptions that may be raised by command server. most of # known exceptions are caught by dispatch. except error.Abort as inst: - ui.error(_(b'abort: %s\n') % inst) + ui.error(_(b'abort: %s\n') % inst.message) except IOError as inst: if inst.errno != errno.EPIPE: raise diff --git a/mercurial/crecord.py b/mercurial/crecord.py --- a/mercurial/crecord.py +++ b/mercurial/crecord.py @@ -1808,7 +1808,7 @@ are you sure you want to review/edit and try: patch = self.ui.edit(patch.getvalue(), b"", action=b"diff") except error.Abort as exc: - self.errorstr = stringutil.forcebytestr(exc) + self.errorstr = exc.message return None finally: self.stdscr.clear() diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -1770,7 +1770,7 @@ def debuginstall(ui, **opts): try: username = ui.username() except error.Abort as e: - err = stringutil.forcebytestr(e) + err = e.message problems += 1 fm.condwrite( diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -288,7 +288,7 @@ def dispatch(req): if req.fmsg: req.ui.fmsg = req.fmsg except error.Abort as inst: - ferr.write(_(b"abort: %s\n") % inst) + ferr.write(_(b"abort: %s\n") % inst.message) if inst.hint: ferr.write(_(b"(%s)\n") % inst.hint) return -1 diff --git a/mercurial/error.py b/mercurial/error.py --- a/mercurial/error.py +++ b/mercurial/error.py @@ -155,7 +155,15 @@ class ConflictResolutionRequired(Interve class Abort(Hint, Exception): """Raised if a command needs to print an error and exit.""" - __bytes__ = _tobytes + def __init__(self, message, hint=None): + self.message = message + self.hint = hint + # Pass the message into the Exception constructor to help extensions + # that look for exc.args[0]. + Exception.__init__(self, message) + + def __bytes__(self): + return self.message if pycompat.ispy3: diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -493,7 +493,7 @@ class hgweb(object): except error.Abort as e: res.status = b'403 Forbidden' res.headers[b'Content-Type'] = ctype - return rctx.sendtemplate(b'error', error=pycompat.bytestr(e)) + return rctx.sendtemplate(b'error', error=e.message) except ErrorResponse as e: for k, v in e.headers: res.headers[k] = v diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -355,7 +355,10 @@ def _donormalize(patterns, default, root except error.Abort as inst: raise error.Abort( b'%s: %s' - % (pat, inst[0]) # pytype: disable=unsupported-operands + % ( + pat, + inst.message, + ) # pytype: disable=unsupported-operands ) except IOError as inst: if warn: diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -216,7 +216,7 @@ def callcatch(ui, func): except error.WdirUnsupported: ui.error(_(b"abort: working directory revision cannot be specified\n")) except error.Abort as inst: - ui.error(_(b"abort: %s\n") % inst) + ui.error(_(b"abort: %s\n") % inst.message) if inst.hint: ui.error(_(b"(%s)\n") % inst.hint) except ImportError as inst: diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -39,7 +39,6 @@ from .utils import ( dateutil, hashutil, procutil, - stringutil, ) hg = None @@ -84,9 +83,7 @@ def annotatesubrepoerror(func): except error.Abort as ex: subrepo = subrelpath(self) errormsg = ( - stringutil.forcebytestr(ex) - + b' ' - + _(b'(in subrepository "%s")') % subrepo + ex.message + b' ' + _(b'(in subrepository "%s")') % subrepo ) # avoid handling this exception by raising a SubrepoAbort exception raise SubrepoAbort( diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py --- a/mercurial/wireprotov1server.py +++ b/mercurial/wireprotov1server.py @@ -497,11 +497,11 @@ def getbundle(repo, proto, others): # cleanly forward Abort error to the client if not exchange.bundle2requested(opts.get(b'bundlecaps')): if proto.name == b'http-v1': - return wireprototypes.ooberror(pycompat.bytestr(exc) + b'\n') + return wireprototypes.ooberror(exc.message + b'\n') raise # cannot do better for bundle1 + ssh # bundle2 request expect a bundle2 reply bundler = bundle2.bundle20(repo.ui) - manargs = [(b'message', pycompat.bytestr(exc))] + manargs = [(b'message', exc.message)] advargs = [] if exc.hint is not None: advargs.append((b'hint', exc.hint)) @@ -684,7 +684,7 @@ def unbundle(repo, proto, heads): # We did not change it to minimise code change. # This need to be moved to something proper. # Feel free to do it. - procutil.stderr.write(b"abort: %s\n" % exc) + procutil.stderr.write(b"abort: %s\n" % exc.message) if exc.hint is not None: procutil.stderr.write(b"(%s)\n" % exc.hint) procutil.stderr.flush() @@ -733,7 +733,7 @@ def unbundle(repo, proto, heads): if exc.params: errpart.addparam(b'params', b'\0'.join(exc.params)) except error.Abort as exc: - manargs = [(b'message', stringutil.forcebytestr(exc))] + manargs = [(b'message', exc.message)] advargs = [] if exc.hint is not None: advargs.append((b'hint', exc.hint)) diff --git a/tests/bruterebase.py b/tests/bruterebase.py --- a/tests/bruterebase.py +++ b/tests/bruterebase.py @@ -52,7 +52,7 @@ def debugbruterebase(ui, repo, source, d try: rebase.rebase(ui, repo, dest=dest, rev=[spec]) except error.Abort as ex: - summary = b'ABORT: %s' % ex + summary = b'ABORT: %s' % ex.message except Exception as ex: summary = b'CRASH: %s' % ex else: diff --git a/tests/test-url.py b/tests/test-url.py --- a/tests/test-url.py +++ b/tests/test-url.py @@ -392,7 +392,7 @@ def test_url(): >>> try: ... u = url(b'file://mercurial-scm.org/foo') ... except error.Abort as e: - ... forcebytestr(e) + ... e.message 'file:// URLs can only refer to localhost' Empty URL: