sapling/errorredirect.py
Jun Wu f4389dfd0d errorredirect: simplify environment variables
Summary:
Add $WARNING to make it easier to get the original behavior (print the
`***` contact support stuff). Remove misc environment variables included
in $WARNING to make the code simpler and less dependent.

Besides, store traceback in $TRACE so that it will be easier to read it
for multiple times. For example, try to upload it (first read) and if
failed, print it locally (second read). Otherwise we need ugly hack like
`A=$(cat)` in the script.

Test Plan: Check the new examples manually and run test-errorredirect.t

Reviewers: #sourcecontrol, ttung, rmcelroy

Reviewed By: rmcelroy

Differential Revision: https://phabricator.fb.com/D2770557

Tasks: 9259456

Signature: t1:2770557:1450384683:672e76752040d3d1b440522dd54ac43306c76bf9
2015-12-17 20:28:31 +00:00

61 lines
1.9 KiB
Python

# 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
a custom shell script. This is useful for futher handling the error,
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.
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.
Examples::
[errorredirect]
script = tee hgerr.log && echo 'Error written to hgerr.log'
[errorredirect]
script = echo "$WARNING$TRACE" >&2
[errorredirect]
script = (echo "$WARNING"; cat) | cat >&2
"""
import os
import subprocess
import sys
def wrapui(ui):
class errorredirectui(ui.__class__):
def errorredirect(self, content, env):
script = self.config('errorredirect', 'script')
if not script:
return
p = subprocess.Popen(script, shell=True, stdin=subprocess.PIPE,
env=dict(os.environ.items() + env.items()))
p.communicate(content)
# prevent hg from printing the stack trace
sys.exit(1)
def log(self, event, *msg, **opts):
if event == 'commandexception':
warning, traceback = msg[-2:]
self.errorredirect(traceback,
{'WARNING': warning, 'TRACE': traceback})
return super(errorredirectui, self).log(event, *msg, **opts)
ui.__class__ = errorredirectui
def uisetup(ui):
wrapui(ui)