1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
# coding=utf8
from functools import wraps
import traceback
import re
import sys
from UltiSnips import vim_helper
def wrap(func):
"""Decorator that will catch any Exception that 'func' throws and displays
it in a new Vim scratch buffer."""
@wraps(func)
def wrapper(self, *args, **kwds):
try:
return func(self, *args, **kwds)
except Exception as e: # pylint: disable=bare-except
msg = """An error occured. This is either a bug in UltiSnips or a bug in a
snippet definition. If you think this is a bug, please report it to
https://github.com/SirVer/ultisnips/issues/new
Please read and follow:
https://github.com/SirVer/ultisnips/blob/master/CONTRIBUTING.md#reproducing-bugs
Following is the full stack trace:
"""
msg += traceback.format_exc()
if hasattr(e, "snippet_info"):
msg += "\nSnippet, caused error:\n"
msg += re.sub(r"^(?=\S)", " ", e.snippet_info, flags=re.MULTILINE)
# snippet_code comes from _python_code.py, it's set manually for
# providing error message with stacktrace of failed python code
# inside of the snippet.
if hasattr(e, "snippet_code"):
_, _, tb = sys.exc_info()
tb_top = traceback.extract_tb(tb)[-1]
msg += "\nExecuted snippet code:\n"
lines = e.snippet_code.split("\n")
for number, line in enumerate(lines, 1):
msg += str(number).rjust(3)
prefix = " " if line else ""
if tb_top[1] == number:
prefix = " > "
msg += prefix + line + "\n"
# Vim sends no WinLeave msg here.
if hasattr(self, "_leaving_buffer"):
self._leaving_buffer() # pylint:disable=protected-access
vim_helper.new_scratch_buffer(msg)
return wrapper
|