32 lines
921 B
Python
32 lines
921 B
Python
|
from typing import Iterator
|
||
|
from typing_extensions import NoReturn
|
||
|
|
||
|
import sys
|
||
|
import traceback
|
||
|
from contextlib import contextmanager
|
||
|
|
||
|
|
||
|
@contextmanager
|
||
|
def catch_errors(module_path: str, line: int) -> Iterator[None]:
|
||
|
try:
|
||
|
yield
|
||
|
except Exception:
|
||
|
crash_report(module_path, line)
|
||
|
|
||
|
|
||
|
def crash_report(module_path: str, line: int) -> 'NoReturn':
|
||
|
# Adapted from report_internal_error in mypy
|
||
|
err = sys.exc_info()[1]
|
||
|
tb = traceback.extract_stack()[:-4]
|
||
|
# Excise all the traceback from the test runner
|
||
|
for i, x in enumerate(tb):
|
||
|
if x.name == 'pytest_runtest_call':
|
||
|
tb = tb[i + 1:]
|
||
|
break
|
||
|
tb2 = traceback.extract_tb(sys.exc_info()[2])[1:]
|
||
|
print('Traceback (most recent call last):')
|
||
|
for s in traceback.format_list(tb + tb2):
|
||
|
print(s.rstrip('\n'))
|
||
|
print(f'{module_path}:{line}: {type(err).__name__}: {err}')
|
||
|
raise SystemExit(2)
|