Skip to content
This repository was archived by the owner on Jun 25, 2020. It is now read-only.

Commit 97504ef

Browse files
committed
feature: also capture silent exceptions. Now our interpreter also reports exceptions in for instance callback threads
1 parent 1e9c589 commit 97504ef

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

src/python_interpreter.cc

+27-13
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,23 @@ Python::Interpreter::Interpreter(){
6262
Py_Initialize();
6363
argv=Py_DecodeLocale("",&size);
6464
PySys_SetArgv(0,&argv);
65+
auto sys=get_loaded_module("sys");
66+
auto exc_func=[](pybind11::object type,pybind11::object value,pybind11::object traceback){
67+
if(!given_exception_matches(type,PyExc_ImportError))
68+
Terminal::get().print(Error(type,value,traceback),true);
69+
else
70+
Terminal::get().print(SyntaxError(type,value,traceback),true);
71+
};
72+
sys.attr("excepthook")=pybind11::cpp_function(exc_func);
6573
boost::filesystem::directory_iterator end_it;
6674
for(boost::filesystem::directory_iterator it(plugin_path);it!=end_it;it++){
6775
auto module_name=it->path().stem().string();
6876
if(module_name!="__pycache__"){
6977
auto module=import(module_name);
7078
if(!module){
79+
auto msg="Error loading plugin `"+module_name+"`:\n";
7180
auto err=std::string(Error());
72-
auto msg="Error loading plugin "+module_name+":\n";
73-
Terminal::get().print(msg,true);
74-
Terminal::get().print(err+"\n");
81+
Terminal::get().print(msg+err+"\n");
7582
}
7683
}
7784
}
@@ -89,6 +96,15 @@ pybind11::module Python::reload(pybind11::module &module){
8996
return pybind11::module(PyImport_ReloadModule(module.ptr()),false);
9097
}
9198

99+
Python::SyntaxError::SyntaxError(pybind11::object type,pybind11::object value,pybind11::object traceback)
100+
: Error(type,value,traceback){}
101+
102+
Python::Error::Error(pybind11::object type,pybind11::object value,pybind11::object traceback){
103+
exp=type;
104+
val=value;
105+
trace=traceback;
106+
}
107+
92108
void Python::Interpreter::add_path(const boost::filesystem::path &path){
93109
if(path.empty())
94110
return;
@@ -115,14 +131,12 @@ pybind11::object Python::error_occured(){
115131
return pybind11::object(PyErr_Occurred(),true);
116132
}
117133

118-
bool Python::thrown_exception_matches(Error::Type type){
119-
pybind11::object compare;
120-
switch(type){
121-
case Error::Type::Syntax : compare=pybind11::object(PyExc_SyntaxError,false);
122-
case Error::Type::Attribute : compare=pybind11::object(PyExc_AttributeError,false);
123-
case Error::Type::Import : compare=pybind11::object(PyExc_ImportError,false);
124-
}
125-
return PyErr_GivenExceptionMatches(Python::error_occured().ptr(), compare.ptr());
134+
bool Python::thrown_exception_matches(pybind11::handle exception_type){
135+
return PyErr_ExceptionMatches(exception_type.ptr());
136+
}
137+
138+
bool Python::given_exception_matches(const pybind11::object &exception, pybind11::handle exception_type){
139+
return PyErr_GivenExceptionMatches(exception.ptr(),exception_type.ptr());
126140
}
127141

128142
Python::Error::Error(){
@@ -131,7 +145,7 @@ Python::Error::Error(){
131145
PyErr_Fetch(&exp.ptr(),&val.ptr(),&trace.ptr());
132146
PyErr_NormalizeException(&exp.ptr(),&val.ptr(),&trace.ptr());
133147
}catch(const std::exception &e) {
134-
Terminal::get().print(e.what());
148+
Terminal::get().print(e.what(),true);
135149
}
136150
}
137151
}
@@ -160,5 +174,5 @@ Python::SyntaxError::operator std::string(){
160174
}
161175

162176
Python::Error::operator bool(){
163-
return exp;
177+
return exp || trace || val;
164178
}

src/python_interpreter.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,23 @@ class Python {
2929
class Error {
3030
public:
3131
Error();
32+
Error(pybind11::object type,pybind11::object value,pybind11::object traceback);
3233
operator std::string();
3334
operator bool();
3435
pybind11::object exp, val, trace;
35-
enum Type {Syntax,Attribute,Import};
3636
};
3737

38-
class SyntaxError : Error{
38+
class SyntaxError : public Error{
3939
public:
4040
SyntaxError();
41+
SyntaxError(pybind11::object type,pybind11::object value,pybind11::object traceback);
4142
operator std::string();
4243
std::string exp, text;
4344
int line_number, line_offset;
4445
};
4546

46-
bool static thrown_exception_matches(Error::Type exception_type);
47+
bool static thrown_exception_matches(pybind11::handle exception_type);
48+
bool static given_exception_matches(const pybind11::object &exception,pybind11::handle exception_type);
4749

4850
private:
4951
pybind11::object static error_occured();

src/window.cc

+4-3
Original file line numberDiff line numberDiff line change
@@ -253,21 +253,22 @@ void Window::set_menu_actions() {
253253
}
254254
}
255255
while(file_path.has_parent_path()){
256-
if(file_path == Config::get().python.plugin_directory){
256+
auto parent=file_path.parent_path();
257+
if(parent==Config::get().python.plugin_directory){
257258
auto stem=file_path.stem().string();
258259
auto module=Python::get_loaded_module(stem);
259260
module=module ? Python::reload(module) : Python::import(stem);
260261
if(module)
261262
Terminal::get().print("Plugin `"+stem+"` was reloaded\n");
262263
else {
263-
if(Python::thrown_exception_matches(Python::Error::Type::Syntax))
264+
if(Python::thrown_exception_matches(PyExc_SyntaxError))
264265
Terminal::get().print(Python::SyntaxError());
265266
else
266267
Terminal::get().print(Python::Error());
267268
}
268269
break;
269270
}
270-
file_path=file_path.parent_path();
271+
file_path=parent;
271272
}
272273
}
273274
}

0 commit comments

Comments
 (0)