From c9ef6281ff3c6a38fbb7da7b7b05d55f1405d326 Mon Sep 17 00:00:00 2001 From: "roberto@voldermort" Date: Fri, 13 Aug 2010 17:37:34 +0200 Subject: [PATCH] added --catch-exceptions, it will print app exceptions to your browser --- ini.c | 2 +- pyutils.c | 8 +++++--- spooler.c | 2 +- uwsgi.c | 3 ++- uwsgi.h | 3 ++- uwsgiconfig.py | 2 +- wsgi_handlers.c | 34 ++++++++++++++++++++++++++++++++-- 7 files changed, 44 insertions(+), 10 deletions(-) diff --git a/ini.c b/ini.c index bdc8d4a2..e55e5f9a 100644 --- a/ini.c +++ b/ini.c @@ -131,7 +131,7 @@ void uwsgi_ini_config(char *file, struct option *long_options) { if (key[0] == '[') { section = key; } - else if (key[0] == ';') { + else if (key[0] == ';' || key[0] == '#') { // this is a comment } else { diff --git a/pyutils.c b/pyutils.c index 10134440..7121006f 100644 --- a/pyutils.c +++ b/pyutils.c @@ -160,13 +160,15 @@ clear2: } -PyObject *python_call(PyObject *callable, PyObject *args) { +PyObject *python_call(PyObject *callable, PyObject *args, int catch) { PyObject *pyret; pyret = PyEval_CallObject(callable, args); if (PyErr_Occurred()) { - PyErr_Print(); + if (!catch) { + PyErr_Print(); + } } #ifdef UWSGI_DEBUG @@ -183,7 +185,7 @@ PyObject *python_call(PyObject *callable, PyObject *args) { int uwsgi_python_call(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req, PyObject *callable, PyObject *args) { - wsgi_req->async_result = python_call(callable, args); + wsgi_req->async_result = python_call(callable, args, 0); if (wsgi_req->async_result) { while ( manage_python_response(uwsgi, wsgi_req) != UWSGI_OK) { diff --git a/spooler.c b/spooler.c index 05fc8535..5753cb4e 100644 --- a/spooler.c +++ b/spooler.c @@ -249,7 +249,7 @@ void spooler(struct uwsgi_server *uwsgi, PyObject * uwsgi_module_dict) { } - spool_result = python_call(spooler_callable, spool_tuple); + spool_result = python_call(spooler_callable, spool_tuple, 0); if (!spool_result) { PyErr_Print(); uwsgi_log( "error detected. spool request canceled.\n"); diff --git a/uwsgi.c b/uwsgi.c index 03a866aa..88019afd 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -395,6 +395,7 @@ int main(int argc, char *argv[], char *envp[]) { {"http", required_argument, 0, LONG_ARGS_HTTP}, {"http-only", no_argument, &uwsgi.http_only, 1}, #endif + {"catch-exceptions", no_argument, &uwsgi.catch_exceptions, 1}, {"mode", required_argument, 0, LONG_ARGS_MODE}, {"env", required_argument, 0, LONG_ARGS_ENV}, {"version", no_argument, 0, LONG_ARGS_MODE}, @@ -1262,7 +1263,7 @@ int main(int argc, char *argv[], char *envp[]) { PyTuple_SetItem(udp_callable_args, 0, PyString_FromString(udp_client_addr)); PyTuple_SetItem(udp_callable_args, 1, PyInt_FromLong(ntohs(udp_client.sin_port))); PyTuple_SetItem(udp_callable_args, 2, PyString_FromStringAndSize(uwsgi.wsgi_req->buffer, rlen)); - PyObject *udp_response = python_call(udp_callable, udp_callable_args); + PyObject *udp_response = python_call(udp_callable, udp_callable_args, 0); if (udp_response) { Py_DECREF(udp_response); } diff --git a/uwsgi.h b/uwsgi.h index d65e70d9..80ce9882 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -653,6 +653,7 @@ struct uwsgi_server { #endif char *chdir2; + int catch_exceptions; }; struct uwsgi_cluster_node { @@ -923,7 +924,7 @@ PyObject *py_uwsgi_stackless(PyObject *, PyObject *) ; int manage_python_response(struct uwsgi_server *, struct wsgi_request *); int uwsgi_python_call(struct uwsgi_server *, struct wsgi_request *, PyObject *, PyObject *); -PyObject *python_call(PyObject *, PyObject *); +PyObject *python_call(PyObject *, PyObject *, int); #ifdef UWSGI_SENDFILE PyObject *py_uwsgi_sendfile(PyObject *, PyObject *) ; diff --git a/uwsgiconfig.py b/uwsgiconfig.py index b49dd0db..d966bb07 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -314,7 +314,7 @@ def parse_vars(): else: libs.append(pcreconf) - if EVDIS: + if HTTP: cflags.append("-DUWSGI_HTTP") gcc_list.append('http') diff --git a/wsgi_handlers.c b/wsgi_handlers.c index 11e9f211..04c05bd6 100644 --- a/wsgi_handlers.c +++ b/wsgi_handlers.c @@ -352,7 +352,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req #ifdef UWSGI_PROFILER if (uwsgi->enable_profiler == 1) { PyDict_SetItem(wi->pymain_dict, PyString_FromFormat("uwsgi_environ__%d", wsgi_req->app_id), wsgi_req->async_environ); - wsgi_req->async_result = python_call(wi->wsgi_cprofile_run, wsgi_req->async_args); + wsgi_req->async_result = python_call(wi->wsgi_cprofile_run, wsgi_req->async_args, 0); if (wsgi_req->async_result) { wsgi_req->async_result = PyDict_GetItemString(wi->pymain_dict, "uwsgi_out"); Py_INCREF((PyObject*)wsgi_req->async_result); @@ -364,7 +364,7 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ); - wsgi_req->async_result = python_call(wsgi_req->async_app, wsgi_req->async_args); + wsgi_req->async_result = python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi->catch_exceptions); #ifdef UWSGI_PROFILER } @@ -384,6 +384,36 @@ int uwsgi_request_wsgi(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req } + else if (uwsgi->catch_exceptions) { + + wsgi_req->response_size += write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len); + wsgi_req->response_size += write(wsgi_req->poll.fd, " 500 Internal Server Error\r\n", 28 ); + wsgi_req->response_size += write(wsgi_req->poll.fd, "Content-type: text/plain\r\n\r\n", 28 ); + wsgi_req->header_cnt = 1 ; + + /* + sorry that is a hack to avoid the rewrite of PyErr_Print + temporarily map (using dup2) stderr to wsgi_req->poll.fd + */ + int tmp_stderr = dup(2); + if (tmp_stderr < 0) { + uwsgi_error("dup()"); + goto clear; + } + // map 2 to wsgi_req + if (dup2(wsgi_req->poll.fd, 2) < 0) { + close(tmp_stderr); + uwsgi_error("dup2()"); + goto clear; + } + // print the error + PyErr_Print(); + // ...resume the original stderr, in case of error we are damaged forever !!! + if (dup2(tmp_stderr, 2) < 0) { + uwsgi_error("dup2()"); + } + close(tmp_stderr); + } clear: