2015-12-04 02:03:07 +03:00
|
|
|
# errorredirect.py
|
|
|
|
#
|
|
|
|
# Copyright 2015 Facebook, Inc.
|
|
|
|
#
|
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
"""redirect error message
|
|
|
|
|
|
|
|
Redirect error message, the stack trace, of an uncaught exception to
|
2016-04-04 22:48:01 +03:00
|
|
|
a custom shell script. This is useful for further handling the error,
|
2015-12-04 02:03:07 +03:00
|
|
|
for example posting it to a support group and logging it somewhere.
|
|
|
|
|
|
|
|
The config option errorredirect.script is the shell script to execute.
|
|
|
|
If it's empty, the extension will do nothing and fallback to the old
|
|
|
|
behavior.
|
|
|
|
|
2015-12-17 23:28:31 +03:00
|
|
|
Two environment variables are set: TRACE is the stack trace, which
|
|
|
|
is the same as piped content. WARNING is the warning message, which
|
|
|
|
usually contains contact message and software versions, etc.
|
2015-12-04 02:03:07 +03:00
|
|
|
|
|
|
|
Examples::
|
|
|
|
|
|
|
|
[errorredirect]
|
|
|
|
script = tee hgerr.log && echo 'Error written to hgerr.log'
|
|
|
|
|
|
|
|
[errorredirect]
|
2015-12-17 23:28:31 +03:00
|
|
|
script = echo "$WARNING$TRACE" >&2
|
|
|
|
|
|
|
|
[errorredirect]
|
|
|
|
script = (echo "$WARNING"; cat) | cat >&2
|
2015-12-04 02:03:07 +03:00
|
|
|
"""
|
|
|
|
|
2017-04-04 20:27:30 +03:00
|
|
|
import signal
|
2015-12-04 02:03:07 +03:00
|
|
|
import subprocess
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
import traceback
|
errorredirect: modify errorredirect extension to send crash log to scuba table
Summary: Modify error redirect extension to send crash log, type and traceback to scuba table hgerrors
Test Plan:
Sample that is being sent to Scuba:
```
{
"int":{"time":1498528572},
"normal":{
"host":"devvm26497.prn1",
"metrics_type":"hgerrors",
"msg":"exception has occurred: ** unknown exception encountered, please report by visiting\n** Source Control @ FB group\n** Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]\n** Mercurial Distributed SCM (version 4.2.1+842-79c3f212a9c9)\n** Extensions loaded: tweakdefaults, hgk, absorb, arcdiff, automv, blackbox, chistedit, color, debugcommitmessage, debuginhibit, evolve, fbhistedit, githelp, hiddenerror, histedit, inhibit, journal, logginghelper, lz4revlog, morestatus, moreversion, myparent, pager, patchrmdir, perftweaks, phabdiff, phabstatus, phrevset, pullcreatemarkers, purge, rage, rebase, record, remotefilelog, remotenames, reset, sampling, fbshow, sigtrace, simplecache, smartlog, sshaskpass, strip, directaccess, uncommit, conflictinfo, extorder, obsshelve, sqldirstate, fastmanifest, hgsubversion, traceprof, dialect, grpcheck, errorredirect, fbamend, pushvars, pushrebase\n",
"traceback":"Traceback (most recent call last):\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 326, in _callcatch\n return scmutil.callcatch(ui, func)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/scmutil.py\", line 145, in callcatch\n return func()\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 308, in _runcatchfunc\n return _dispatch(req)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 938, in _dispatch\n cmdpats, cmdoptions)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/fastmanifest\/cachemanager.py\", line 318, in runcommandtrigger\n result = orig(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/fastmanifest\/__init__.py\", line 175, in _logonexit\n r = orig(ui, repo, cmd, fullargs, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/perftweaks.py\", line 263, in _tracksparseprofiles\n res = runcommand(lui, repo, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/perftweaks.py\", line 248, in _trackdirstatesizes\n res = runcommand(lui, repo, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/journal.py\", line 76, in runcommand\n return orig(lui, repo, cmd, fullargs, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 674, in runcommand\n ret = _runcommand(ui, options, cmd, d)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/pager.py\", line 69, in pagecmd\n return orig(ui, options, cmd, cmdfunc)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 946, in _runcommand\n return cmdfunc()\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 935, in <lambda>\n d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/absorb\/__init__.py\", line 977, in _amendcmd\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/tweakdefaults.py\", line 627, in cmd\n return origcmd(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/tweakdefaults.py\", line 694, in amendcmd\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/automv.py\", line 63, in mvcheck\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/data\/users\/lsen\/facebook-hg-rpms\/fb-hgext\/hgext3rd\/fbamend\/__init__.py\", line 169, in amend\n raise Exception(\"testing\")\nException: testing\n",
"type":"<type 'exceptions.Exception'>"}
}
```
Reviewers: juehui, akushner, durham
Reviewed By: durham
Subscribers: medson, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D5326253
Tasks: 19602850
Signature: t1:5326253:1498577444:c62977ec782519a22b9dc64b33f2a575c544b83c
2017-06-27 19:44:29 +03:00
|
|
|
import sys
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
|
|
|
|
from mercurial import (
|
|
|
|
dispatch,
|
2017-01-03 16:59:55 +03:00
|
|
|
encoding,
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
extensions,
|
|
|
|
)
|
|
|
|
|
2017-04-04 20:27:30 +03:00
|
|
|
def _printtrace(ui, warning):
|
|
|
|
# Like dispatch.handlecommandexception, but avoids an unnecessary ui.log
|
|
|
|
ui.warn(warning)
|
|
|
|
return False # return value for "handlecommandexception", re-raises
|
|
|
|
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
def _handlecommandexception(orig, ui):
|
2017-04-04 20:27:30 +03:00
|
|
|
warning = dispatch._exceptionwarning(ui)
|
|
|
|
trace = traceback.format_exc()
|
|
|
|
|
|
|
|
# let blackbox log it (if it is configured to do so)
|
|
|
|
ui.log("commandexception", "%s\n%s\n", warning, trace)
|
errorredirect: modify errorredirect extension to send crash log to scuba table
Summary: Modify error redirect extension to send crash log, type and traceback to scuba table hgerrors
Test Plan:
Sample that is being sent to Scuba:
```
{
"int":{"time":1498528572},
"normal":{
"host":"devvm26497.prn1",
"metrics_type":"hgerrors",
"msg":"exception has occurred: ** unknown exception encountered, please report by visiting\n** Source Control @ FB group\n** Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]\n** Mercurial Distributed SCM (version 4.2.1+842-79c3f212a9c9)\n** Extensions loaded: tweakdefaults, hgk, absorb, arcdiff, automv, blackbox, chistedit, color, debugcommitmessage, debuginhibit, evolve, fbhistedit, githelp, hiddenerror, histedit, inhibit, journal, logginghelper, lz4revlog, morestatus, moreversion, myparent, pager, patchrmdir, perftweaks, phabdiff, phabstatus, phrevset, pullcreatemarkers, purge, rage, rebase, record, remotefilelog, remotenames, reset, sampling, fbshow, sigtrace, simplecache, smartlog, sshaskpass, strip, directaccess, uncommit, conflictinfo, extorder, obsshelve, sqldirstate, fastmanifest, hgsubversion, traceprof, dialect, grpcheck, errorredirect, fbamend, pushvars, pushrebase\n",
"traceback":"Traceback (most recent call last):\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 326, in _callcatch\n return scmutil.callcatch(ui, func)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/scmutil.py\", line 145, in callcatch\n return func()\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 308, in _runcatchfunc\n return _dispatch(req)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 938, in _dispatch\n cmdpats, cmdoptions)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/fastmanifest\/cachemanager.py\", line 318, in runcommandtrigger\n result = orig(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/fastmanifest\/__init__.py\", line 175, in _logonexit\n r = orig(ui, repo, cmd, fullargs, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/perftweaks.py\", line 263, in _tracksparseprofiles\n res = runcommand(lui, repo, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/perftweaks.py\", line 248, in _trackdirstatesizes\n res = runcommand(lui, repo, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/journal.py\", line 76, in runcommand\n return orig(lui, repo, cmd, fullargs, *args)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 674, in runcommand\n ret = _runcommand(ui, options, cmd, d)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/pager.py\", line 69, in pagecmd\n return orig(ui, options, cmd, cmdfunc)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 946, in _runcommand\n return cmdfunc()\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/dispatch.py\", line 935, in <lambda>\n d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/absorb\/__init__.py\", line 977, in _amendcmd\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/tweakdefaults.py\", line 627, in cmd\n return origcmd(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext3rd\/tweakdefaults.py\", line 694, in amendcmd\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/extensions.py\", line 273, in closure\n return func(*(args + a), **kw)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/usr\/lib64\/python2.7\/site-packages\/hgext\/automv.py\", line 63, in mvcheck\n return orig(ui, repo, *pats, **opts)\n File \"\/usr\/lib64\/python2.7\/site-packages\/mercurial\/util.py\", line 1056, in check\n return func(*args, **kwargs)\n File \"\/data\/users\/lsen\/facebook-hg-rpms\/fb-hgext\/hgext3rd\/fbamend\/__init__.py\", line 169, in amend\n raise Exception(\"testing\")\nException: testing\n",
"type":"<type 'exceptions.Exception'>"}
}
```
Reviewers: juehui, akushner, durham
Reviewed By: durham
Subscribers: medson, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D5326253
Tasks: 19602850
Signature: t1:5326253:1498577444:c62977ec782519a22b9dc64b33f2a575c544b83c
2017-06-27 19:44:29 +03:00
|
|
|
ui.log("hgerrors", "exception has occurred: %s",
|
|
|
|
warning, type=str(sys.exc_type.__name__), traceback=trace)
|
2017-04-04 20:27:30 +03:00
|
|
|
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
script = ui.config('errorredirect', 'script')
|
|
|
|
if not script:
|
2018-01-23 23:08:57 +03:00
|
|
|
return orig(ui)
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
|
2017-04-04 20:27:30 +03:00
|
|
|
# run the external script
|
2017-01-03 16:59:55 +03:00
|
|
|
env = encoding.environ.copy()
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
env['WARNING'] = warning
|
|
|
|
env['TRACE'] = trace
|
2017-04-04 20:27:30 +03:00
|
|
|
|
|
|
|
# decide whether to use shell smartly, see 9335dc6b2a9c in hg
|
|
|
|
shell = any(c in script for c in "|&;<>()$`\\\"' \t\n*?[#~=%")
|
|
|
|
|
|
|
|
try:
|
|
|
|
p = subprocess.Popen(script, shell=shell, stdin=subprocess.PIPE,
|
|
|
|
env=env)
|
|
|
|
p.communicate(trace)
|
|
|
|
except StandardError:
|
|
|
|
# The binary cannot be executed, or some other issues. For example,
|
|
|
|
# "script" is not in PATH, and shell is False; or the peer closes the
|
|
|
|
# pipe early. Fallback to the plain error reporting.
|
|
|
|
return _printtrace(ui, warning)
|
|
|
|
else:
|
|
|
|
ret = p.returncode
|
|
|
|
|
|
|
|
# Python returns negative exit code for signal-terminated process. The
|
|
|
|
# shell converts singal-terminated process to a positive exit code by
|
|
|
|
# +128. Ctrl+C generates SIGTERM. Re-report the error unless the
|
|
|
|
# process exits cleanly or is terminated by SIGTERM (Ctrl+C).
|
|
|
|
ctrlc = (ret == signal.SIGTERM + 128) or (ret == -signal.SIGTERM)
|
|
|
|
if ret != 0 and not ctrlc:
|
|
|
|
return _printtrace(ui, warning)
|
|
|
|
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
return True # do not re-raise
|
2015-12-04 02:03:07 +03:00
|
|
|
|
|
|
|
def uisetup(ui):
|
errorredirect: wrap handlecommandexception instead of sys.exit
Summary:
Since `handlecommandexception` is in core, wrap it to suppress original
crash text, instead of doing an ugly `sys.exit()`. It's much simpler and
cleaner than before. It also fixes an issue with current chg since chgserver
will print an traceback when it encounters SystemExit.
Although `logtoprocess` are doing very similar things with `errorredirect`,
it currently cannot replace `errorredirect` because we need synchronized
behavior to return the user to their shell prompt correctly. If we can get
the synchronized behavior and a way to disable builtin warning (may be tricky)
in `logtoprocess` upstream, the `errorredirect` extension could be just a thin
wrapper around `logtoprocess` using `setconfig`.
Besides, we no longer need `suppresscommandfailure` since the feature will
be either in `errorredirect` or `logtoprocess`.
Test Plan:
Run `hg crash` with `errorredirect.script` set to confirm it is compatible
with the old behavior.
Also run unittest `test-errorredirect.t`
Reviewers: #sourcecontrol, ttung, mjpieters
Reviewed By: mjpieters
Subscribers: rmcelroy, durham, lcharignon, mjpieters
Differential Revision: https://phabricator.fb.com/D3191840
Signature: t1:3191840:1461088280:77febd539c2f38a55778af3977738c045f63a0d8
2016-04-19 20:59:22 +03:00
|
|
|
extensions.wrapfunction(dispatch, 'handlecommandexception',
|
|
|
|
_handlecommandexception)
|