Add a mechanism for logging errors instead of swallowing exceptions

This commit is contained in:
mjv761 2020-09-06 12:22:47 -06:00
parent bb5ab9ddb5
commit ab0714ef1d
5 changed files with 55 additions and 15 deletions

View File

@ -2613,7 +2613,8 @@ class DebuggerUI(FrameVarInfoKeeper):
try:
class_name = frame.f_locals["self"].__class__.__name__
except Exception:
pass
from pudb.lowlevel import ui_log
ui_log.exception('Failed to determine class name')
return StackFrame(frame is self.debugger.curframe,
code.co_name, class_name,

View File

@ -28,6 +28,26 @@ THE SOFTWARE.
from pudb.py3compat import PY3, text_type
import logging
ui_formatter = logging.Formatter(
fmt='\n*** Pudb UI Exception Encountered: %(message)s ***\n'
)
ui_handler = logging.StreamHandler()
ui_handler.setFormatter(ui_formatter)
ui_log = logging.getLogger('ui')
ui_log.setLevel(logging.CRITICAL)
ui_log.addHandler(ui_handler)
settings_formatter = logging.Formatter(
fmt='\n*** Pudb Settings Exception Encountered: %(message)s ***\n'
)
settings_handler = logging.StreamHandler()
settings_handler.setFormatter(settings_formatter)
settings_log = logging.getLogger('settings')
settings_log.setLevel(logging.CRITICAL)
settings_log.addHandler(settings_handler)
# {{{ breakpoint validity

View File

@ -15,17 +15,27 @@ def main():
# python -m pudb -m http.server -h
# where the -h will be passed to the http.server module
parser.add_argument("-m", "--module", action='store_true',
help="Debug as module or package instead of as a script")
help="Debug as module or package instead of as a script")
parser.add_argument("-le", "--log-errors", action='store_true',
help="If an unexpected exception is encountered, "
"log the exception information to stderr",
default=False)
parser.add_argument("--pre-run", metavar="COMMAND",
help="Run command before each program run",
default="")
help="Run command before each program run",
default="")
parser.add_argument('script_args', nargs=argparse.REMAINDER,
help="Arguments to pass to script or module")
options = parser.parse_args()
args = options.script_args
if options.log_errors:
import logging
from pudb.lowlevel import ui_log, settings_log
ui_log.setLevel(logging.ERROR)
settings_log.setLevel(logging.ERROR)
options_kwargs = {
'pre_run': options.pre_run,
'steal_output': options.steal_output,

View File

@ -25,12 +25,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import os
import sys
from pudb.py3compat import ConfigParser
from pudb.lowlevel import lookup_module, get_breakpoint_invalid_reason
from pudb.lowlevel import (lookup_module, get_breakpoint_invalid_reason,
settings_log)
# minor LGPL violation: stolen from python-xdg
@ -85,7 +85,7 @@ def load_config():
if cparser.has_section(CONF_SECTION):
conf_dict.update(dict(cparser.items(CONF_SECTION)))
except Exception:
pass
settings_log.exception('Failed to load config')
conf_dict.setdefault("shell", "internal")
conf_dict.setdefault("theme", "classic")
@ -121,7 +121,7 @@ def load_config():
else:
conf_dict[name] = True
except Exception:
pass
settings_log.exception('Failed to process config')
normalize_bool_inplace("line_numbers")
normalize_bool_inplace("wrap_variables")
@ -148,7 +148,7 @@ def save_config(conf_dict):
cparser.write(outf)
outf.close()
except Exception:
pass
settings_log.exception('Failed to save config')
def edit_config(ui, conf_dict):

View File

@ -33,6 +33,8 @@ THE SOFTWARE.
import urwid
import inspect
from pudb.lowlevel import ui_log
try:
import numpy
HAVE_NUMPY = 1
@ -285,7 +287,7 @@ def type_stringifier(value):
try:
return text_type(value)
except Exception:
pass
ui_log.exception('string safe type stringifier failed')
elif hasattr(type(value), "safely_stringify_for_pudb"):
try:
@ -293,7 +295,7 @@ def type_stringifier(value):
# and return nonsense.
result = value.safely_stringify_for_pudb()
except Exception:
pass
ui_log.exception('safely_stringify_for_pudb call failed')
else:
if isinstance(result, string_types):
return text_type(result)
@ -371,6 +373,7 @@ class ValueWalker:
# repr() on a random object.
displayed_value = type_stringifier(value) \
+ " (!! %s error !!)" % iinfo.display_type
ui_log.exception('stringifier failed')
if iinfo.show_detail:
if iinfo.access_level == "public":
@ -414,21 +417,27 @@ class ValueWalker:
key_it = value.keys()
else:
key_it = value.iterkeys()
except Exception:
except AttributeError:
# keys or iterkeys doesn't exist, not worth mentioning!
pass
except Exception:
ui_log.exception('Failed to obtain key iterator')
if key_it is None:
try:
len_value = len(value)
except Exception:
except TypeError:
# no __len__ defined on the value, not worth mentioning!
pass
except Exception:
ui_log.exception('Failed to determine container length')
else:
try:
value[0]
except IndexError:
key_it = []
except Exception:
pass
ui_log.exception('Item is not iterable')
else:
key_it = xrange(len_value)
@ -456,7 +465,7 @@ class ValueWalker:
try:
key_its.append(dir(value))
except Exception:
pass
ui_log.exception('Failed to lookup attributes')
keys = [key
for ki in key_its