diff --git a/pre_commit/error_handler.py b/pre_commit/error_handler.py index 3b0a4c51..946f134c 100644 --- a/pre_commit/error_handler.py +++ b/pre_commit/error_handler.py @@ -44,9 +44,11 @@ def _log_and_exit(msg, exc, formatted): def error_handler(): try: yield - except FatalError as e: - _log_and_exit('An error has occurred', e, traceback.format_exc()) - except Exception as e: - _log_and_exit( - 'An unexpected error has occurred', e, traceback.format_exc(), - ) + except (Exception, KeyboardInterrupt) as e: + if isinstance(e, FatalError): + msg = 'An error has occurred' + elif isinstance(e, KeyboardInterrupt): + msg = 'Interrupted (^C)' + else: + msg = 'An unexpected error has occurred' + _log_and_exit(msg, e, traceback.format_exc()) diff --git a/tests/error_handler_test.py b/tests/error_handler_test.py index 6aebe5a3..1b222f90 100644 --- a/tests/error_handler_test.py +++ b/tests/error_handler_test.py @@ -73,6 +73,29 @@ def test_error_handler_uncaught_error(mocked_log_and_exit): ) +def test_error_handler_keyboardinterrupt(mocked_log_and_exit): + exc = KeyboardInterrupt() + with error_handler.error_handler(): + raise exc + + mocked_log_and_exit.assert_called_once_with( + 'Interrupted (^C)', + exc, + # Tested below + mock.ANY, + ) + assert re.match( + r'Traceback \(most recent call last\):\n' + r' File ".+pre_commit.error_handler.py", line \d+, in error_handler\n' + r' yield\n' + r' File ".+tests.error_handler_test.py", line \d+, ' + r'in test_error_handler_keyboardinterrupt\n' + r' raise exc\n' + r'KeyboardInterrupt\n', + mocked_log_and_exit.call_args[0][2], + ) + + def test_log_and_exit(cap_out, mock_store_dir): with pytest.raises(SystemExit): error_handler._log_and_exit(