]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41468: Improve and test IDLE run error exit (GH-21798)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 9 Aug 2020 20:26:37 +0000 (13:26 -0700)
committerGitHub <noreply@github.com>
Sun, 9 Aug 2020 20:26:37 +0000 (13:26 -0700)
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@udel.edu>
Lib/idlelib/NEWS.txt
Lib/idlelib/idle_test/test_run.py
Lib/idlelib/run.py
Misc/NEWS.d/next/IDLE/2020-08-09-13-42-55.bpo-41468.zkP0_Y.rst [new file with mode: 0644]

index 41ff15d84eac7de73e27c43e2b8ae2f236b29809..f395f0c72f6626a682229d85dae7bb3a8e0ddc90 100644 (file)
@@ -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.
index e2bdf1cfee3521321505bf293eaca808307ea2ca..469c13d756d5e8b8d671ce9ad390f61e49238b9a 100644 (file)
@@ -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 @@ class RecursionLimitTest(unittest.TestCase):
         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)
index 5bd84aadcd8011ea1eda835ccb242ada0964ee7f..1e84ecc6584ef1c77ecee138a81cef23fd353743 100644 (file)
@@ -387,14 +387,21 @@ class MyRPCServer(rpc.RPCServer):
             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 (file)
index 0000000..e41c7d5
--- /dev/null
@@ -0,0 +1 @@
+Improve IDLE run crash error message (which users should never see).