[Python-checkins] bpo-41468: Improve and test IDLE run error exit (GH-21798)

Miss Islington (bot) webhook-mailer at python.org
Sun Aug 9 16:26:41 EDT 2020


https://github.com/python/cpython/commit/61f23cb62d6bdd72b61fc36abf4c1492493d71af
commit: 61f23cb62d6bdd72b61fc36abf4c1492493d71af
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-08-09T13:26:37-07:00
summary:

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 f2e161c27964a59bc5ab20d96f87ba5862c6222d)

Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>

files:
A Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst
M Lib/idlelib/NEWS.txt
M Lib/idlelib/idle_test/test_run.py
M Lib/idlelib/run.py

diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 41ff15d84eac7..f395f0c72f662 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -3,6 +3,9 @@ Released on 2020-09-14?
 ======================================
 
 
+bpo-41468: Improve IDLE run crash error message (which users should
+never see).
+
 bpo-41373: Save files loaded with no line ending, as when blank, or
 different line endings, by setting its line ending to the system
 default. Fix regression in 3.8.4 and 3.9.0b4.
diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py
index e2bdf1cfee352..469c13d756d5e 100644
--- a/Lib/idlelib/idle_test/test_run.py
+++ b/Lib/idlelib/idle_test/test_run.py
@@ -1,9 +1,10 @@
-"Test run, coverage 42%."
+"Test run, coverage 49%."
 
 from idlelib import run
 import unittest
 from unittest import mock
-from test.support import captured_stderr
+from idlelib.idle_test.mock_idle import Func
+from test.support import captured_output, captured_stderr
 
 import io
 import sys
@@ -323,5 +324,32 @@ def func(): "docstring"
         self.assertEqual(func.__doc__, "more")
 
 
+class HandleErrorTest(unittest.TestCase):
+    # Method of MyRPCServer
+    func = Func()
+    @mock.patch('idlelib.run.thread.interrupt_main', new=func)
+    def test_error(self):
+        eq = self.assertEqual
+        with captured_output('__stderr__') as err:
+            try:
+                raise EOFError
+            except EOFError:
+                run.MyRPCServer.handle_error(None, 'abc', '123')
+            eq(run.exit_now, True)
+            run.exit_now = False
+            eq(err.getvalue(), '')
+
+            try:
+                raise IndexError
+            except IndexError:
+                run.MyRPCServer.handle_error(None, 'abc', '123')
+            eq(run.quitting, True)
+            run.quitting = False
+            msg = err.getvalue()
+            self.assertIn('abc', msg)
+            self.assertIn('123', msg)
+            self.assertIn('IndexError', msg)
+            eq(self.func.called, 2)
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 5bd84aadcd801..1e84ecc6584ef 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -387,14 +387,21 @@ def handle_error(self, request, client_address):
             thread.interrupt_main()
         except:
             erf = sys.__stderr__
-            print('\n' + '-'*40, file=erf)
-            print('Unhandled server exception!', file=erf)
-            print('Thread: %s' % threading.current_thread().name, file=erf)
-            print('Client Address: ', client_address, file=erf)
-            print('Request: ', repr(request), file=erf)
-            traceback.print_exc(file=erf)
-            print('\n*** Unrecoverable, server exiting!', file=erf)
-            print('-'*40, file=erf)
+            print(textwrap.dedent(f"""
+            {'-'*40}
+            Unhandled exception in user code execution server!'
+            Thread: {threading.current_thread().name}
+            IDLE Client Address: {client_address}
+            Request: {request!r}
+            """), file=erf)
+            traceback.print_exc(limit=-20, file=erf)
+            print(textwrap.dedent(f"""
+            *** Unrecoverable, server exiting!
+
+            Users should never see this message; it is likely transient.
+            If this recurs, report this with a copy of the message
+            and an explanation of how to make it repeat.
+            {'-'*40}"""), file=erf)
             quitting = True
             thread.interrupt_main()
 
diff --git a/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst b/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst
new file mode 100644
index 0000000000000..e41c7d574905c
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst
@@ -0,0 +1 @@
+Improve IDLE run crash error message (which users should never see).



More information about the Python-checkins mailing list