Issue #28410: Added _PyErr_FormatFromCause() -- the helper for raising
new exception with setting current exception as __cause__.

_PyErr_FormatFromCause(exception, format, args...) is equivalent to Python

    raise exception(format % args) from sys.exc_info()[1]
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 747eda0..f9afece 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2198,20 +2198,18 @@
     }
     else {
         if (err_occurred) {
-            PyObject *exc, *val, *tb;
-            PyErr_Fetch(&exc, &val, &tb);
-
             Py_DECREF(result);
 
-            if (func)
-                PyErr_Format(PyExc_SystemError,
-                             "%R returned a result with an error set",
-                             func);
-            else
-                PyErr_Format(PyExc_SystemError,
-                             "%s returned a result with an error set",
-                             where);
-            _PyErr_ChainExceptions(exc, val, tb);
+            if (func) {
+                _PyErr_FormatFromCause(PyExc_SystemError,
+                        "%R returned a result with an error set",
+                        func);
+            }
+            else {
+                _PyErr_FormatFromCause(PyExc_SystemError,
+                        "%s returned a result with an error set",
+                        where);
+            }
 #ifdef Py_DEBUG
             /* Ensure that the bug is caught in debug mode */
             Py_FatalError("a function returned a result with an error set");