Merge pull request #592 from seletskiy/show-backtrace-on-error
Show backtrace on error in the scratch buffer.
This commit is contained in:
commit
1ce44ac9c8
@ -6,6 +6,7 @@
|
||||
import re
|
||||
|
||||
import vim
|
||||
import textwrap
|
||||
|
||||
from UltiSnips import _vim
|
||||
from UltiSnips.compatibility import as_unicode
|
||||
@ -116,7 +117,31 @@ class SnippetDefinition(object):
|
||||
|
||||
snip = SnippetUtilForAction(locals)
|
||||
|
||||
exec(code, {'snip': snip})
|
||||
try:
|
||||
exec(code, {'snip': snip})
|
||||
except Exception as e:
|
||||
e.snippet_info = textwrap.dedent("""
|
||||
Defined in: {}
|
||||
Trigger: {}
|
||||
Description: {}
|
||||
Context: {}
|
||||
Pre-expand: {}
|
||||
Post-expand: {}
|
||||
""").format(
|
||||
self._location,
|
||||
self._trigger,
|
||||
self._description,
|
||||
self._context_code if self._context_code else '<none>',
|
||||
self._actions['pre_expand'] if 'pre_expand' in self._actions
|
||||
else '<none>',
|
||||
self._actions['post_expand'] if 'post_expand' in self._actions
|
||||
else '<none>',
|
||||
code,
|
||||
)
|
||||
|
||||
e.snippet_code = code
|
||||
|
||||
raise
|
||||
|
||||
return snip
|
||||
|
||||
|
@ -8,7 +8,9 @@ from functools import wraps
|
||||
import os
|
||||
import platform
|
||||
import traceback
|
||||
import sys
|
||||
import vim
|
||||
import re
|
||||
from contextlib import contextmanager
|
||||
|
||||
from UltiSnips import _vim
|
||||
@ -57,7 +59,7 @@ def err_to_scratch_buffer(func):
|
||||
def wrapper(self, *args, **kwds):
|
||||
try:
|
||||
return func(self, *args, **kwds)
|
||||
except: # pylint: disable=bare-except
|
||||
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
|
||||
@ -65,7 +67,28 @@ 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.
|
||||
self._leaving_buffer() # pylint:disable=protected-access
|
||||
_vim.new_scratch_buffer(msg)
|
||||
|
@ -267,7 +267,11 @@ class PythonCode(NoneditableTextObject):
|
||||
self._snip._reset(ct) # pylint:disable=protected-access
|
||||
|
||||
for code in self._codes:
|
||||
exec(code, self._locals) # pylint:disable=exec-used
|
||||
try:
|
||||
exec(code, self._locals) # pylint:disable=exec-used
|
||||
except Exception as e:
|
||||
e.snippet_code = code
|
||||
raise
|
||||
|
||||
rv = as_unicode(
|
||||
self._snip.rv if self._snip._rv_changed # pylint:disable=protected-access
|
||||
|
@ -239,3 +239,78 @@ endsnippet
|
||||
"""}
|
||||
keys = 'ab' + EX
|
||||
wanted = 'x first a bob b y'
|
||||
|
||||
|
||||
class ParseSnippets_PrintPythonStacktrace(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
snippet test
|
||||
`!p abc()`
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = " > abc"
|
||||
|
||||
|
||||
class ParseSnippets_PrintPythonStacktraceMultiline(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
snippet test
|
||||
`!p if True:
|
||||
qwe()`
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = " > \s+qwe"
|
||||
|
||||
|
||||
class ParseSnippets_PrintErroneousSnippet(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
snippet test "asd()" e
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = "Trigger: test"
|
||||
|
||||
|
||||
class ParseSnippets_PrintErroneousSnippetContext(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
snippet test "asd()" e
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = "Context: asd"
|
||||
|
||||
|
||||
class ParseSnippets_PrintErroneousSnippetPreAction(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
pre_expand "asd()"
|
||||
snippet test
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = "Pre-expand: asd"
|
||||
|
||||
|
||||
class ParseSnippets_PrintErroneousSnippetPostAction(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
post_expand "asd()"
|
||||
snippet test
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = "Post-expand: asd"
|
||||
|
||||
class ParseSnippets_PrintErroneousSnippetLocation(_VimTest):
|
||||
files = { 'us/all.snippets': r"""
|
||||
post_expand "asd()"
|
||||
snippet test
|
||||
endsnippet
|
||||
"""}
|
||||
keys = 'test' + EX
|
||||
wanted = keys
|
||||
expected_error = "Defined in: .*/all.snippets"
|
||||
|
Loading…
Reference in New Issue
Block a user