diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c
index c9182eb71a3002b605988e4c775ac7d5113a5653..ed1f21cd6a51a83bd57157f16af003654b47b46c 100644
--- a/src/pl/plpython/plpy_spi.c
+++ b/src/pl/plpython/plpy_spi.c
@@ -407,16 +407,6 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
 		{
 			MemoryContext oldcontext2;
 
-			/*
-			 * Save tuple descriptor for later use by result set metadata
-			 * functions.  Save it in TopMemoryContext so that it survives
-			 * outside of an SPI context.  We trust that PLy_result_dealloc()
-			 * will clean it up when the time is right.
-			 */
-			oldcontext2 = MemoryContextSwitchTo(TopMemoryContext);
-			result->tupdesc = CreateTupleDescCopy(tuptable->tupdesc);
-			MemoryContextSwitchTo(oldcontext2);
-
 			if (rows)
 			{
 				Py_DECREF(result->rows);
@@ -425,23 +415,33 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
 				PLy_input_tuple_funcs(&args, tuptable->tupdesc);
 				for (i = 0; i < rows; i++)
 				{
-					PyObject   *row = PLyDict_FromTuple(&args, tuptable->vals[i],
+					PyObject   *row = PLyDict_FromTuple(&args,
+														tuptable->vals[i],
 														tuptable->tupdesc);
 
 					PyList_SetItem(result->rows, i, row);
 				}
 			}
+
+			/*
+			 * Save tuple descriptor for later use by result set metadata
+			 * functions.  Save it in TopMemoryContext so that it survives
+			 * outside of an SPI context.  We trust that PLy_result_dealloc()
+			 * will clean it up when the time is right.  (Do this as late as
+			 * possible, to minimize the number of ways the tupdesc could get
+			 * leaked due to errors.)
+			 */
+			oldcontext2 = MemoryContextSwitchTo(TopMemoryContext);
+			result->tupdesc = CreateTupleDescCopy(tuptable->tupdesc);
+			MemoryContextSwitchTo(oldcontext2);
 		}
 		PG_CATCH();
 		{
 			MemoryContextSwitchTo(oldcontext);
-			if (!PyErr_Occurred())
-				PLy_exception_set(PLy_exc_error,
-					   "unrecognized error in PLy_spi_execute_fetch_result");
 			PLy_typeinfo_dealloc(&args);
 			SPI_freetuptable(tuptable);
 			Py_DECREF(result);
-			return NULL;
+			PG_RE_THROW();
 		}
 		PG_END_TRY();