mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-07 22:21:47 +00:00
added exception detection
This commit is contained in:
@@ -375,12 +375,6 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_AGAIN;
|
||||
|
||||
clear:
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
|
||||
|
||||
Py_DECREF((PyObject *)wsgi_req->async_result);
|
||||
|
||||
@@ -108,8 +108,6 @@ struct uwsgi_option uwsgi_python_options[] = {
|
||||
{"ini-paste", required_argument, 0, "load a paste.deploy config file containing uwsgi section", uwsgi_opt_ini_paste, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
{"ini-paste-logged", required_argument, 0, "load a paste.deploy config file containing uwsgi section (load loggers too)", uwsgi_opt_ini_paste, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
#endif
|
||||
{"catch-exceptions", no_argument, 0, "report exception has http output (discouraged)", uwsgi_opt_true, &up.catch_exceptions, 0},
|
||||
{"ignore-script-name", no_argument, 0, "ignore SCRIPT_NAME", uwsgi_opt_true, &up.ignore_script_name, 0},
|
||||
{"reload-os-env", no_argument, 0, "force reload of os.environ at each request", uwsgi_opt_true, &up.reload_os_env, 0},
|
||||
#ifndef UWSGI_PYPY
|
||||
{"no-site", no_argument, 0, "do not import site module", uwsgi_opt_true, &Py_NoSiteFlag, 0},
|
||||
|
||||
@@ -8,20 +8,103 @@ int manage_python_response(struct wsgi_request *wsgi_req) {
|
||||
return uwsgi_response_subhandler_wsgi(wsgi_req);
|
||||
}
|
||||
|
||||
char *uwsgi_python_get_exception_type(PyObject *exc) {
|
||||
char *class_name = NULL;
|
||||
if (PyClass_Check(exc)) {
|
||||
class_name = PyString_AsString( ((PyClassObject*)(exc))->cl_name );
|
||||
}
|
||||
else {
|
||||
class_name = (char *) ((PyTypeObject*)exc)->tp_name;
|
||||
}
|
||||
|
||||
if (class_name) {
|
||||
char *dot = strrchr(class_name, '.');
|
||||
if (dot) class_name = dot+1;
|
||||
|
||||
PyObject *module_name = PyObject_GetAttrString(exc, "__module__");
|
||||
if (module_name) {
|
||||
char *mod_name = PyString_AsString(module_name);
|
||||
if (mod_name && strcmp(mod_name, "exceptions") ) {
|
||||
char *ret = uwsgi_concat3(mod_name, ".", class_name);
|
||||
Py_DECREF(module_name);
|
||||
return ret;
|
||||
}
|
||||
Py_DECREF(module_name);
|
||||
return uwsgi_str(class_name);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uwsgi_python_get_exception_value(PyObject *value) {
|
||||
return PyString_AsString( PyObject_Str(value) );
|
||||
}
|
||||
|
||||
char *uwsgi_python_get_exception_repr(PyObject *exc, PyObject *value) {
|
||||
char *exc_type = uwsgi_python_get_exception_type(exc);
|
||||
char *exc_value = uwsgi_python_get_exception_value(value);
|
||||
|
||||
if (exc_type && exc_value) {
|
||||
return uwsgi_concat3(exc_type, ": ", exc_value);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_python_manage_exceptions(void) {
|
||||
PyObject *type = NULL;
|
||||
PyObject *value = NULL;
|
||||
PyObject *traceback = NULL;
|
||||
|
||||
char *exc_type = NULL;
|
||||
char *exc_value = NULL;
|
||||
char *exc_repr = NULL;
|
||||
|
||||
PyErr_Fetch(&type, &value, &traceback);
|
||||
PyErr_NormalizeException(&type, &value, &traceback);
|
||||
|
||||
if (uwsgi.reload_on_exception_type) {
|
||||
exc_type = uwsgi_python_get_exception_type(type);
|
||||
}
|
||||
|
||||
if (uwsgi.reload_on_exception_value) {
|
||||
exc_value = uwsgi_python_get_exception_value(value);
|
||||
}
|
||||
|
||||
if (uwsgi.reload_on_exception_repr) {
|
||||
exc_repr = uwsgi_python_get_exception_repr(type, value);
|
||||
}
|
||||
|
||||
int ret = uwsgi_manage_exception(exc_type, exc_value, exc_repr);
|
||||
|
||||
// free memory allocated for strcmp
|
||||
if (exc_type) free(exc_type);
|
||||
if (exc_repr) free(exc_repr);
|
||||
|
||||
PyErr_Restore(type, value, traceback);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyObject *pyret;
|
||||
|
||||
//uwsgi_log("ready to call %p %p\n", callable, args);
|
||||
|
||||
pyret = PyEval_CallObject(callable, args);
|
||||
pyret = PyEval_CallObject(callable, args);
|
||||
|
||||
//uwsgi_log("called\n");
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
|
||||
int do_exit = uwsgi_python_manage_exceptions();
|
||||
|
||||
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
|
||||
uwsgi_log("Memory Error detected !!!\n");
|
||||
}
|
||||
|
||||
// this can be in a spooler or in the master
|
||||
if (uwsgi.mywid > 0) {
|
||||
uwsgi.workers[uwsgi.mywid].exceptions++;
|
||||
@@ -32,6 +115,10 @@ PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi
|
||||
if (!catch) {
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
if (do_exit) {
|
||||
exit(UWSGI_EXCEPTION_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
|
||||
@@ -136,9 +136,6 @@ struct uwsgi_python {
|
||||
|
||||
char *callable;
|
||||
|
||||
int ignore_script_name;
|
||||
int catch_exceptions;
|
||||
|
||||
int *current_recursion_depth;
|
||||
struct _frame **current_frame;
|
||||
|
||||
|
||||
@@ -225,12 +225,6 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_AGAIN;
|
||||
|
||||
clear:
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
|
||||
|
||||
Py_DECREF((PyObject *)wsgi_req->async_result);
|
||||
|
||||
@@ -363,7 +363,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
if (wsgi_req->appid_len == 0) {
|
||||
if (!up.ignore_script_name) {
|
||||
if (!uwsgi.ignore_script_name) {
|
||||
wsgi_req->appid = wsgi_req->script_name;
|
||||
wsgi_req->appid_len = wsgi_req->script_name_len;
|
||||
}
|
||||
@@ -466,7 +466,7 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
}
|
||||
|
||||
else if (up.catch_exceptions) {
|
||||
else if (uwsgi.catch_exceptions) {
|
||||
|
||||
// LOCK THIS PART
|
||||
|
||||
@@ -501,6 +501,14 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
close(tmp_stderr);
|
||||
}
|
||||
|
||||
// this object must be freed/cleared always
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
|
||||
clear:
|
||||
|
||||
up.reset_ts(wsgi_req, wi);
|
||||
|
||||
@@ -159,7 +159,7 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
// call
|
||||
|
||||
PyTuple_SetItem(wsgi_req->async_args, 0, wsgi_req->async_environ);
|
||||
return python_call(wsgi_req->async_app, wsgi_req->async_args, up.catch_exceptions, wsgi_req);
|
||||
return python_call(wsgi_req->async_app, wsgi_req->async_args, uwsgi.catch_exceptions, wsgi_req);
|
||||
}
|
||||
|
||||
int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {
|
||||
@@ -280,12 +280,6 @@ clear:
|
||||
if (wsgi_req->sendfile_fd != -1) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_sendfile);
|
||||
}
|
||||
if (wsgi_req->async_input) {
|
||||
Py_DECREF((PyObject *)wsgi_req->async_input);
|
||||
}
|
||||
if (wsgi_req->async_environ) {
|
||||
PyDict_Clear(wsgi_req->async_environ);
|
||||
}
|
||||
Py_XDECREF((PyObject *)wsgi_req->async_placeholder);
|
||||
clear2:
|
||||
Py_DECREF((PyObject *)wsgi_req->async_result);
|
||||
|
||||
Reference in New Issue
Block a user