mirror of https://github.com/CGAL/cgal
fixup! Better exception handling (with Qt Script)
This commit is contained in:
parent
ed2eae8879
commit
54dbab9d3c
|
|
@ -433,17 +433,25 @@ void MainWindow::evaluate_script(QString script,
|
|||
const bool quiet) {
|
||||
QScriptValue value = script_engine->evaluate(script, filename);
|
||||
if(script_engine->hasUncaughtException()) {
|
||||
QScriptValue js_exception = script_engine->uncaughtException();
|
||||
QScriptValue js_bt =js_exception.property("backtrace");
|
||||
QStringList bt = script_engine->uncaughtExceptionBacktrace();
|
||||
if(js_bt.isValid()) {
|
||||
QStringList other_bt;
|
||||
qScriptValueToSequence(js_bt, other_bt);
|
||||
if(!other_bt.isEmpty()) bt = other_bt;
|
||||
}
|
||||
if(!quiet) {
|
||||
QTextStream err(stderr);
|
||||
err << "Qt Script exception:\n"
|
||||
<< script_engine->uncaughtException().toString()
|
||||
<< js_exception.toString()
|
||||
<< "\nBacktrace:\n";
|
||||
Q_FOREACH(QString line, script_engine->uncaughtExceptionBacktrace()) {
|
||||
Q_FOREACH(QString line, bt) {
|
||||
err << " " << line << "\n";
|
||||
}
|
||||
}
|
||||
throw CGAL::Three::Script_exception
|
||||
(script_engine->uncaughtException().toString().toStdString());
|
||||
(script_engine->uncaughtException().toString(), bt);
|
||||
}
|
||||
else if(!quiet && !value.isNull() && !value.isUndefined()) {
|
||||
QTextStream(stderr) << "Qt Script evaluated to \""
|
||||
|
|
@ -468,6 +476,10 @@ void MainWindow::enableScriptDebugger(bool b /* = true */)
|
|||
if(b) {
|
||||
debugger->action(QScriptEngineDebugger::InterruptAction)->trigger();
|
||||
}
|
||||
else {
|
||||
std::cerr << "Detach the script debugger\n";
|
||||
debugger->detach();
|
||||
}
|
||||
}
|
||||
return;
|
||||
# endif
|
||||
|
|
@ -1389,6 +1401,13 @@ bool MainWindow::loadScript(QFileInfo info)
|
|||
return false;
|
||||
}
|
||||
|
||||
void MainWindow::throw_exception() {
|
||||
wrap_a_call_to_cpp([]() {
|
||||
throw std::runtime_error("Exception thrown in "
|
||||
"MainWindow::throw_exception()");
|
||||
}, this, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLoadScript_triggered()
|
||||
{
|
||||
#if defined(QT_SCRIPT_LIB)
|
||||
|
|
|
|||
|
|
@ -210,6 +210,8 @@ public Q_SLOTS:
|
|||
*/
|
||||
void enableScriptDebugger(bool = true);
|
||||
|
||||
/// This slot is used to test exception handling in Qt Scripts.
|
||||
void throw_exception();
|
||||
protected Q_SLOTS:
|
||||
|
||||
//!Gets the new selected item(s) from the sceneView and updates the scene
|
||||
|
|
|
|||
|
|
@ -139,13 +139,11 @@ private:
|
|||
};
|
||||
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/exceptions.h>
|
||||
|
||||
using namespace CGAL::Three;
|
||||
class Polyhedron_demo_trivial_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_plugin_interface,
|
||||
protected QScriptable
|
||||
public Polyhedron_demo_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
|
|
@ -163,13 +161,6 @@ public:
|
|||
return false;}
|
||||
public Q_SLOTS:
|
||||
|
||||
/// This slot is used to test exception handling in Qt Scripts.
|
||||
void throw_exception() {
|
||||
wrap_a_call_to_cpp([]() {
|
||||
throw std::runtime_error("Exception thrown in "
|
||||
"Trivial_plugin::throw_exception()");
|
||||
}, this, __FILE__, __LINE__);
|
||||
}
|
||||
void bbox();
|
||||
void enableAction();
|
||||
|
||||
|
|
|
|||
|
|
@ -47,11 +47,12 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv,
|
|||
QCommandLineOption no_try_catch("no-try-catch",
|
||||
tr("Do not catch uncaught exceptions."));
|
||||
parser.addOption(no_try_catch);
|
||||
#ifdef QT_SCRIPTTOOLS_LIB
|
||||
QCommandLineOption debug_scripts("debug-scripts",
|
||||
tr("Use the scripts debugger."));
|
||||
parser.addOption(debug_scripts);
|
||||
#endif
|
||||
QCommandLineOption no_debug_scripts("no-debug-scripts",
|
||||
tr("Do not use the scripts debugger."));
|
||||
parser.addOption(no_debug_scripts);
|
||||
QCommandLineOption no_autostart("no-autostart",
|
||||
tr("Ignore the autostart.js file, if any."));
|
||||
parser.addOption(no_autostart);
|
||||
|
|
@ -74,7 +75,16 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv,
|
|||
if(parser.isSet(debug_scripts)) {
|
||||
mainWindow.enableScriptDebugger();
|
||||
}
|
||||
if(parser.isSet(no_debug_scripts)) {
|
||||
mainWindow.enableScriptDebugger(false);
|
||||
}
|
||||
#else
|
||||
if(parser.isSet(debug_scripts)) {
|
||||
std::cerr << "Qt Script Tools have not been configured!";
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
mainWindow.loadScript(":/cgal/Polyhedron_3/javascript/lib.js");
|
||||
QFileInfo autostart_js("autostart.js");
|
||||
if(!parser.isSet(no_autostart) && autostart_js.exists()) {
|
||||
|
|
|
|||
|
|
@ -26,17 +26,23 @@
|
|||
#include <QScriptable>
|
||||
#include <QScriptContext>
|
||||
#include <boost/optional.hpp>
|
||||
#include <QStringList>
|
||||
|
||||
namespace CGAL{
|
||||
namespace Three{
|
||||
|
||||
struct Script_exception : public std::runtime_error {
|
||||
Script_exception(const std::string& what_arg)
|
||||
: std::runtime_error(what_arg)
|
||||
{}
|
||||
Script_exception(QString what_arg)
|
||||
class Script_exception : public std::runtime_error {
|
||||
QStringList bt;
|
||||
public:
|
||||
Script_exception(QString what_arg,
|
||||
QStringList backtrace)
|
||||
: std::runtime_error(what_arg.toStdString())
|
||||
, bt(backtrace)
|
||||
{}
|
||||
|
||||
QStringList backtrace() const {
|
||||
return bt;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -73,14 +79,41 @@ wrap_a_call_to_cpp(Callable f,
|
|||
return f();
|
||||
}
|
||||
catch(const std::exception& e) {
|
||||
const Script_exception* se = dynamic_cast<const Script_exception*>(&e);
|
||||
QScriptContext* context = qs->context();
|
||||
if(c == PARENT_CONTEXT) context = context->parentContext();
|
||||
QString error = QObject::tr("Error");
|
||||
if(file != 0) error += QObject::tr(" at file %1").arg(file);
|
||||
if(line != -1) error += QString(":%1").arg(line);
|
||||
error += QString(":\n%1").arg(e.what());
|
||||
QStringList qt_bt = context->backtrace();
|
||||
if(se) qt_bt = se->backtrace();
|
||||
std::cerr << "Backtrace:\n";
|
||||
Q_FOREACH(QString s, qt_bt)
|
||||
{
|
||||
std::cerr << " " << qPrintable(s) << std::endl;
|
||||
}
|
||||
context = context->parentContext();
|
||||
if(c == PARENT_CONTEXT) {
|
||||
std::cerr << "> parent";
|
||||
context = context->parentContext();
|
||||
} else {
|
||||
std::cerr << "> current";
|
||||
}
|
||||
std::cerr << " context: "
|
||||
<< qPrintable(context->toString()) << std::endl;
|
||||
QString error;
|
||||
if(se) {
|
||||
error = se->what();
|
||||
} else {
|
||||
error = QObject::tr("Error");
|
||||
QString context;
|
||||
if(file != 0) context += QObject::tr(" at file %1").arg(file);
|
||||
if(line != -1) context += QString(":%1").arg(line);
|
||||
if(!context.isNull()) {
|
||||
error += context;
|
||||
qt_bt.push_front(QObject::tr("<cpp>") + context);
|
||||
}
|
||||
error += QString(": %1").arg(e.what());
|
||||
}
|
||||
QScriptValue v = context->throwError(error);
|
||||
v.setProperty("backtrace", context->backtrace().join(";"));
|
||||
v.setProperty("backtrace",
|
||||
qScriptValueFromSequence(context->engine(), qt_bt));
|
||||
std::cerr << "result after throwError: "
|
||||
<< qPrintable(v.toString()) << std::endl;
|
||||
return Return_type();
|
||||
|
|
|
|||
Loading…
Reference in New Issue