UI: errors in buttons now show in info report

Mistakes in button expressions were previously only printed to the console.
This commit is contained in:
2015-05-18 09:12:26 +10:00
parent 3ed009af96
commit 29aae4db38
8 changed files with 85 additions and 27 deletions

View File

@@ -478,6 +478,34 @@ error_cleanup:
}
#endif
PyObject *PyC_ExceptionBuffer_Simple(void)
{
PyObject *string_io_buf;
PyObject *error_type, *error_value, *error_traceback;
if (!PyErr_Occurred())
return NULL;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
if (error_value == NULL) {
return NULL;
}
string_io_buf = PyObject_Str(error_value);
/* Python does this too */
if (UNLIKELY(string_io_buf == NULL)) {
string_io_buf = PyUnicode_FromFormat(
"<unprintable %s object>", Py_TYPE(error_value)->tp_name);
}
PyErr_Restore(error_type, error_value, error_traceback);
PyErr_Print();
PyErr_Clear();
return string_io_buf;
}
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)

View File

@@ -32,6 +32,7 @@ void PyC_ObSpit(const char *name, PyObject *var);
void PyC_LineSpit(void);
void PyC_StackSpit(void);
PyObject * PyC_ExceptionBuffer(void);
PyObject * PyC_ExceptionBuffer_Simple(void);
PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
PyObject * PyC_FrozenSetFromStrings(const char **strings);
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);

View File

@@ -595,7 +595,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const bool ver
if (error_ret) {
if (verbose) {
BPy_errors_to_report(CTX_wm_reports(C));
BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
}
else {
PyErr_Clear();

View File

@@ -82,10 +82,9 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool
}
short BPy_errors_to_report(ReportList *reports)
bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location)
{
PyObject *pystring;
PyObject *pystring_format = NULL; /* workaround, see below */
const char *cstring;
const char *filename;
@@ -101,31 +100,49 @@ short BPy_errors_to_report(ReportList *reports)
return 1;
}
pystring = PyC_ExceptionBuffer();
if (use_full) {
pystring = PyC_ExceptionBuffer();
}
else {
pystring = PyC_ExceptionBuffer_Simple();
}
if (pystring == NULL) {
BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert");
return 0;
}
PyC_FileAndNum(&filename, &lineno);
if (filename == NULL)
filename = "<unknown location>";
cstring = _PyUnicode_AsString(pystring);
if (use_location) {
PyObject *pystring_format; /* workaround, see below */
PyC_FileAndNum(&filename, &lineno);
if (filename == NULL) {
filename = "<unknown location>";
}
#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", cstring, filename, lineno);
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", cstring, filename, lineno);
#else
pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
cstring = _PyUnicode_AsString(pystring_format);
BKE_report(reports, RPT_ERROR, cstring);
pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
cstring = _PyUnicode_AsString(pystring_format);
BKE_report(reports, RPT_ERROR, cstring);
Py_DECREF(pystring_format); /* workaround */
#endif
}
else {
BKE_report(reports, RPT_ERROR, cstring);
}
/* not exactly needed. just for testing */
fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
Py_DECREF(pystring);
Py_DECREF(pystring_format); /* workaround */
return 1;
}
bool BPy_errors_to_report(ReportList *reports)
{
return BPy_errors_to_report_ex(reports, true, true);
}

View File

@@ -40,7 +40,8 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
/* error reporting */
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
short BPy_errors_to_report(struct ReportList *reports);
bool BPy_errors_to_report_ex(struct ReportList *reports, const bool use_full, const bool use_location);
bool BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
struct bContext *BPy_GetContext(void);