refactored catch_exceptions

This commit is contained in:
Unbit
2013-02-17 11:22:09 +01:00
parent 0a9b5f05b0
commit b5a6da5448
8 changed files with 236 additions and 35 deletions
+5
View File
@@ -1875,5 +1875,10 @@ struct uwsgi_plugin pypy_plugin = {
.code_string = uwsgi_python_code_string,
.exception_class = uwsgi_python_exception_class,
.exception_msg = uwsgi_python_exception_msg,
.exception_repr = uwsgi_python_exception_repr,
.exception_log = uwsgi_python_exception_log,
};
+83
View File
@@ -91,6 +91,89 @@ int uwsgi_python_manage_exceptions(void) {
return ret;
}
struct uwsgi_buffer *uwsgi_python_exception_class(struct wsgi_request *wsgi_req) {
PyObject *type = NULL;
PyObject *value = NULL;
PyObject *traceback = NULL;
struct uwsgi_buffer *ub = NULL;
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
char *class = uwsgi_python_get_exception_type(type);
if (class) {
size_t class_len = strlen(class);
ub = uwsgi_buffer_new(class_len);
if (uwsgi_buffer_append(ub, class, class_len)) {
uwsgi_buffer_destroy(ub);
ub = NULL;
goto end;
}
}
end:
PyErr_Restore(type, value, traceback);
return ub;
}
struct uwsgi_buffer *uwsgi_python_exception_msg(struct wsgi_request *wsgi_req) {
PyObject *type = NULL;
PyObject *value = NULL;
PyObject *traceback = NULL;
struct uwsgi_buffer *ub = NULL;
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
// value could be NULL ?
if (!value) goto end;
char *msg = PyString_AsString( PyObject_Str(value) );
if (msg) {
size_t msg_len = strlen(msg);
ub = uwsgi_buffer_new(msg_len);
if (uwsgi_buffer_append(ub, msg, msg_len)) {
uwsgi_buffer_destroy(ub);
ub = NULL;
goto end;
}
}
end:
PyErr_Restore(type, value, traceback);
return ub;
}
struct uwsgi_buffer *uwsgi_python_exception_repr(struct wsgi_request *wsgi_req) {
struct uwsgi_buffer *ub_class = uwsgi_python_exception_class(wsgi_req);
if (!ub_class) return NULL;
struct uwsgi_buffer *ub_msg = uwsgi_python_exception_msg(wsgi_req);
if (!ub_msg) {
uwsgi_buffer_destroy(ub_class);
return NULL;
}
struct uwsgi_buffer *ub = uwsgi_buffer_new(ub_class->pos + 2 + ub_msg->pos);
if (uwsgi_buffer_append(ub, ub_class->buf, ub_class->pos)) goto error;
if (uwsgi_buffer_append(ub, ": ", 2)) goto error;
if (uwsgi_buffer_append(ub, ub_msg->buf, ub_msg->pos)) goto error;
uwsgi_buffer_destroy(ub_class);
uwsgi_buffer_destroy(ub_msg);
return ub;
error:
uwsgi_buffer_destroy(ub_class);
uwsgi_buffer_destroy(ub_msg);
uwsgi_buffer_destroy(ub);
return NULL;
}
void uwsgi_python_exception_log(struct wsgi_request *wsgi_req) {
PyErr_Print();
}
PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi_request *wsgi_req) {
//uwsgi_log("ready to call %p %p\n", callable, args);
+5
View File
@@ -263,6 +263,11 @@ int uwsgi_python_do_send_headers(struct wsgi_request *);
void *uwsgi_python_tracebacker_thread(void *);
PyObject *uwsgi_python_setup_thread(char *);
struct uwsgi_buffer *uwsgi_python_exception_class(struct wsgi_request *);
struct uwsgi_buffer *uwsgi_python_exception_msg(struct wsgi_request *);
struct uwsgi_buffer *uwsgi_python_exception_repr(struct wsgi_request *);
void uwsgi_python_exception_log(struct wsgi_request *);
#ifdef UWSGI_PYPY
#undef UWSGI_MINTERPRETERS
#endif
+1 -32
View File
@@ -245,7 +245,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
struct uwsgi_app *wi;
int tmp_stderr;
int free_appid = 0;
if (wsgi_req->async_status == UWSGI_AGAIN) {
@@ -380,36 +379,8 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
}
else if (uwsgi.catch_exceptions) {
// LOCK THIS PART
uwsgi_500(wsgi_req);
if (uwsgi_response_write_headers_do(wsgi_req)) goto clear;
/*
sorry that is a hack to avoid the rewrite of PyErr_Print
temporarily map (using dup2) stderr to wsgi_req->fd
*/
tmp_stderr = dup(2);
if (tmp_stderr < 0) {
uwsgi_error("dup()");
goto clear;
}
// map 2 to wsgi_req
if (dup2(wsgi_req->fd, 2) < 0) {
close(tmp_stderr);
uwsgi_error("dup2()");
goto clear;
}
// print the error
UWSGI_GET_GIL
uwsgi_exceptions_catch(wsgi_req);
PyErr_Print();
UWSGI_RELEASE_GIL
// ...resume the original stderr, in case of error we are damaged forever !!!
if (dup2(tmp_stderr, 2) < 0) {
uwsgi_error("dup2()");
}
close(tmp_stderr);
}
// this object must be freed/cleared always
@@ -423,8 +394,6 @@ end:
UWSGI_RELEASE_GIL
clear:
up.reset_ts(wsgi_req, wi);
clear2: