Skip to content

Commit 61f23cb

Browse files
bpo-41468: Improve and test IDLE run error exit (GH-21798)
A message box pops up when an unexpected error stops the run process. Tell users it is likely a random glitch, but report it if not. (cherry picked from commit f2e161c) Co-authored-by: Terry Jan Reedy <[email protected]>
1 parent f421865 commit 61f23cb

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

Lib/idlelib/NEWS.txt

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ Released on 2020-09-14?
33
======================================
44

55

6+
bpo-41468: Improve IDLE run crash error message (which users should
7+
never see).
8+
69
bpo-41373: Save files loaded with no line ending, as when blank, or
710
different line endings, by setting its line ending to the system
811
default. Fix regression in 3.8.4 and 3.9.0b4.

Lib/idlelib/idle_test/test_run.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
"Test run, coverage 42%."
1+
"Test run, coverage 49%."
22

33
from idlelib import run
44
import unittest
55
from unittest import mock
6-
from test.support import captured_stderr
6+
from idlelib.idle_test.mock_idle import Func
7+
from test.support import captured_output, captured_stderr
78

89
import io
910
import sys
@@ -323,5 +324,32 @@ def func(): "docstring"
323324
self.assertEqual(func.__doc__, "more")
324325

325326

327+
class HandleErrorTest(unittest.TestCase):
328+
# Method of MyRPCServer
329+
func = Func()
330+
@mock.patch('idlelib.run.thread.interrupt_main', new=func)
331+
def test_error(self):
332+
eq = self.assertEqual
333+
with captured_output('__stderr__') as err:
334+
try:
335+
raise EOFError
336+
except EOFError:
337+
run.MyRPCServer.handle_error(None, 'abc', '123')
338+
eq(run.exit_now, True)
339+
run.exit_now = False
340+
eq(err.getvalue(), '')
341+
342+
try:
343+
raise IndexError
344+
except IndexError:
345+
run.MyRPCServer.handle_error(None, 'abc', '123')
346+
eq(run.quitting, True)
347+
run.quitting = False
348+
msg = err.getvalue()
349+
self.assertIn('abc', msg)
350+
self.assertIn('123', msg)
351+
self.assertIn('IndexError', msg)
352+
eq(self.func.called, 2)
353+
326354
if __name__ == '__main__':
327355
unittest.main(verbosity=2)

Lib/idlelib/run.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,21 @@ def handle_error(self, request, client_address):
387387
thread.interrupt_main()
388388
except:
389389
erf = sys.__stderr__
390-
print('\n' + '-'*40, file=erf)
391-
print('Unhandled server exception!', file=erf)
392-
print('Thread: %s' % threading.current_thread().name, file=erf)
393-
print('Client Address: ', client_address, file=erf)
394-
print('Request: ', repr(request), file=erf)
395-
traceback.print_exc(file=erf)
396-
print('\n*** Unrecoverable, server exiting!', file=erf)
397-
print('-'*40, file=erf)
390+
print(textwrap.dedent(f"""
391+
{'-'*40}
392+
Unhandled exception in user code execution server!'
393+
Thread: {threading.current_thread().name}
394+
IDLE Client Address: {client_address}
395+
Request: {request!r}
396+
"""), file=erf)
397+
traceback.print_exc(limit=-20, file=erf)
398+
print(textwrap.dedent(f"""
399+
*** Unrecoverable, server exiting!
400+
401+
Users should never see this message; it is likely transient.
402+
If this recurs, report this with a copy of the message
403+
and an explanation of how to make it repeat.
404+
{'-'*40}"""), file=erf)
398405
quitting = True
399406
thread.interrupt_main()
400407

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve IDLE run crash error message (which users should never see).

0 commit comments

Comments
 (0)