52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
|
# coding=utf8
|
||
|
|
||
|
from functools import wraps
|
||
|
import traceback
|
||
|
import re
|
||
|
import sys
|
||
|
|
||
|
from UltiSnips import _vim
|
||
|
|
||
|
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.
|
||
|
|
||
|
Following is the full stack trace:
|
||
|
"""
|
||
|
|
||
|
msg += traceback.format_exc()
|
||
|
if hasattr(e, 'snippet_info'):
|
||
|
msg += "\nSnippet, caused error:\n"
|
||
|
msg += re.sub(
|
||
|
'^(?=\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.new_scratch_buffer(msg)
|
||
|
return wrapper
|