From e189d0a96c4020adca73f8fcff04255b6c9a1c5a Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Thu, 14 Nov 2019 17:48:48 +0300 Subject: Python: fixed handling of errors on response object iteration. According to the documentation, PyIter_Next(): | If there are no remaining values, returns NULL with no exception set. | If an error occurs while retrieving the item, returns NULL and passes | along the exception. Previously, this exception wasn't properly handled and the response was finalized as successful. This issue was introduced in b0148ec28c4d. A check for PyErr_Occurred() located in the code below might print this traceback or occasionally catch an exception from one of the two response close() calls. Albeit that exceptions from the close() calls also need to be catched, it's clear that this particular check wasn't supposed to do so. This is another issue and it will be fixed later. --- src/nxt_python_wsgi.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/nxt_python_wsgi.c') diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c index 6c726a20..e95d4898 100644 --- a/src/nxt_python_wsgi.c +++ b/src/nxt_python_wsgi.c @@ -429,9 +429,21 @@ nxt_python_request_handler(nxt_unit_request_info_t *req) goto fail; } - while (run_ctx.bytes_sent < run_ctx.content_length - && (item = PyIter_Next(iterator))) - { + while (run_ctx.bytes_sent < run_ctx.content_length) { + item = PyIter_Next(iterator); + + if (item == NULL) { + if (nxt_slow_path(PyErr_Occurred() != NULL)) { + nxt_unit_req_error(req, "Python failed to iterate over " + "the application response object"); + PyErr_Print(); + + goto fail; + } + + break; + } + if (nxt_slow_path(!PyBytes_Check(item))) { nxt_unit_req_error(req, "the application returned " "not a bytestring object"); @@ -454,11 +466,6 @@ nxt_python_request_handler(nxt_unit_request_info_t *req) } } - if (nxt_slow_path(PyErr_Occurred() != NULL)) { - nxt_unit_req_error(req, "an application error occurred"); - PyErr_Print(); - } - Py_DECREF(result); rc = NXT_UNIT_OK; -- cgit