From d7e5807b825fcad9819108999f568ee3474ef1a4 Mon Sep 17 00:00:00 2001 From: Thomas Moulard <thomas.moulard@gmail.com> Date: Wed, 14 Mar 2012 17:24:36 +0100 Subject: [PATCH] Make bindings more robust to exceptions. --- src/dynamic-graph-py.cc | 17 ++++-------- src/entity-py.cc | 33 ++++++++-------------- src/exception.hh | 36 ++++++++++++++++++++++++ src/pool-py.cc | 7 ++--- src/signal-base-py.cc | 61 ++++++++++------------------------------- 5 files changed, 71 insertions(+), 83 deletions(-) create mode 100644 src/exception.hh diff --git a/src/dynamic-graph-py.cc b/src/dynamic-graph-py.cc index e49f5ed..b69b26e 100644 --- a/src/dynamic-graph-py.cc +++ b/src/dynamic-graph-py.cc @@ -22,6 +22,8 @@ #include <dynamic-graph/exception-factory.h> #include <dynamic-graph/signal-base.h> +#include "exception.hh" + namespace dynamicgraph { namespace python { @@ -97,10 +99,7 @@ namespace dynamicgraph { try { signalIn->plug(signalOut); - } catch (std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); return Py_BuildValue(""); } @@ -120,17 +119,11 @@ namespace dynamicgraph { if (PyObject_IsTrue(boolean)) { try { DebugTrace::openFile(filename); - } catch (const std::exception& exc) { - PyErr_SetString(PyExc_IOError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); } else { try { DebugTrace::closeFile(filename); - } catch (const std::exception& exc) { - PyErr_SetString(PyExc_IOError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); } } else { return NULL; diff --git a/src/entity-py.cc b/src/entity-py.cc index 53f05c2..558458b 100644 --- a/src/entity-py.cc +++ b/src/entity-py.cc @@ -18,12 +18,14 @@ #include <dynamic-graph/entity.h> #include <dynamic-graph/factory.h> -#include <../src/convert-dg-to-py.hh> #include <dynamic-graph/command.h> #include <dynamic-graph/value.h> #include <dynamic-graph/pool.h> +#include "convert-dg-to-py.hh" +#include "exception.hh" + using dynamicgraph::Entity; using dynamicgraph::SignalBase; using dynamicgraph::command::Command; @@ -71,10 +73,7 @@ namespace dynamicgraph { try { obj = dynamicgraph::FactoryStorage::getInstance()->newEntity (std::string(className), std::string(instanceName)); - } catch (std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); } // Return the pointer as a PyCObject @@ -103,10 +102,7 @@ namespace dynamicgraph { try { name = entity->getName(); - } catch(const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); return Py_BuildValue("s", name.c_str()); } @@ -134,10 +130,8 @@ namespace dynamicgraph { SignalBase<int>* signal = NULL; try { signal = &(entity->getSignal(std::string(name))); - } catch(const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); + // Return the pointer to the signal without destructor since the signal // is not owned by the calling object but by the Entity. return PyCObject_FromVoidPtr((void*)signal, NULL); @@ -171,10 +165,7 @@ namespace dynamicgraph { count++; } return result; - } catch(const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); return NULL; } @@ -238,16 +229,16 @@ namespace dynamicgraph { << exc.what() << "."; PyErr_SetString(dgpyError, ss.str().c_str()) ; return NULL; + } catch (...) { + PyErr_SetString(dgpyError, "Unknown exception"); + return NULL; } } command->setParameterValues(valueVector); try { Value result = command->execute(); return valueToPython(result); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()) ; - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); return NULL; } diff --git a/src/exception.hh b/src/exception.hh new file mode 100644 index 0000000..fddd422 --- /dev/null +++ b/src/exception.hh @@ -0,0 +1,36 @@ +// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. +// +// This file is part of dynamic-graph-python. +// dynamic-graph-python is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either +// version 3 of the License, or (at your option) any later version. +// +// dynamic-graph-python is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Lesser Public License for more details. You should +// have received a copy of the GNU Lesser General Public License along +// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>. + +#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION +# define DYNAMIC_GRAPH_PYTHON_EXCEPTION + +/// \brief Catch all exceptions which may be sent when C++ code is +/// called. +# define CATCH_ALL_EXCEPTIONS() \ + catch (const std::exception& exc) \ + { \ + PyErr_SetString(dgpyError, exc.what()); \ + return NULL; \ + } \ + catch (const char* s) \ + { \ + PyErr_SetString(dgpyError, s); \ + return NULL; \ + } catch (...) { \ + PyErr_SetString(dgpyError, "Unknown exception"); \ + return NULL; \ + } struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n + +#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION diff --git a/src/pool-py.cc b/src/pool-py.cc index a879f96..1858c96 100644 --- a/src/pool-py.cc +++ b/src/pool-py.cc @@ -16,6 +16,8 @@ #include <Python.h> #include <dynamic-graph/pool.h> +#include "exception.hh" + namespace dynamicgraph { namespace python { @@ -28,10 +30,7 @@ namespace dynamicgraph { return NULL; try { PoolStorage::getInstance()->writeGraph (filename); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS(); return Py_BuildValue (""); } } // python diff --git a/src/signal-base-py.cc b/src/signal-base-py.cc index bbbf8db..fc3eddf 100644 --- a/src/signal-base-py.cc +++ b/src/signal-base-py.cc @@ -21,7 +21,9 @@ #include <dynamic-graph/signal.h> #include <dynamic-graph/signal-caster.h> #include <dynamic-graph/linear-algebra.h> -#include <../src/convert-dg-to-py.hh> + +#include "convert-dg-to-py.hh" +#include "exception.hh" using dynamicgraph::SignalBase; @@ -112,10 +114,8 @@ namespace dynamicgraph { std::ostringstream oss; try { obj->display(oss); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); + return Py_BuildValue("s", oss.str().c_str()); } @@ -135,10 +135,7 @@ namespace dynamicgraph { std::ostringstream oss; try { obj->displayDependencies(oss,time); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); return Py_BuildValue("s", oss.str().c_str()); } @@ -176,24 +173,14 @@ namespace dynamicgraph { { return Py_BuildValue("d", sigdouble->accessCopy() ); } - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } catch (...) { - PyErr_SetString(dgpyError, "Unknown exception"); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); + /* Non specific signal: use a generic way. */ std::ostringstream value; try { signal->get(value); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } catch (...) { - PyErr_SetString(dgpyError, "Unknown exception"); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); + std::string valueString = value.str(); return Py_BuildValue("s", valueString.c_str()); } @@ -213,13 +200,8 @@ namespace dynamicgraph { std::string name; try { name = signal->getName(); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } catch (...) { - PyErr_SetString(dgpyError, "Unknown exception"); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); + return Py_BuildValue("s", name.c_str()); } @@ -242,14 +224,7 @@ namespace dynamicgraph { try { signal->set(value); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } catch (...) { - PyErr_SetString(dgpyError, "Unknown exception"); - return NULL; - } - + } CATCH_ALL_EXCEPTIONS (); return Py_BuildValue(""); } @@ -267,10 +242,7 @@ namespace dynamicgraph { SignalBase<int>* signal = (SignalBase<int>*)pointer; try { signal->recompute(time); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); return Py_BuildValue(""); } @@ -287,10 +259,7 @@ namespace dynamicgraph { SignalBase<int>* signal = (SignalBase<int>*)pointer; try { signal->unplug(); - } catch (const std::exception& exc) { - PyErr_SetString(dgpyError, exc.what()); - return NULL; - } + } CATCH_ALL_EXCEPTIONS (); return Py_BuildValue(""); } } -- GitLab