Boost C++ Libraries: Ticket #2781: Add python exception info extractor https://svn.boost.org/trac10/ticket/2781 <p> Something like this is useful when embedding python, and it took me almost an entire day to figure out how to do this. (Having not used boost::python before, I got many crashes when trying to extract data again.) </p> <p> Example: </p> <pre class="wiki"> try { boost::python::eval(...); } catch (boost::python::error_already_set&amp;) { std::string msg = handle_pyerror(); std::cerr &lt;&lt; "Error runnin python code: " &lt;&lt; msg; } </pre><p> Implementation: </p> <div class="wiki-code"><div class="code"><pre><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">handle_pyerror</span><span class="p">()</span> <span class="p">{</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">python</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">ostringstream</span> <span class="n">os</span><span class="p">;</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Python error:</span><span class="se">\n</span><span class="s"> &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">flush</span><span class="p">;</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">type</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="o">*</span><span class="n">val</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="o">*</span><span class="n">tb</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">PyErr_Fetch</span><span class="p">(</span><span class="o">&amp;</span><span class="n">type</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">val</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">tb</span><span class="p">);</span> <span class="n">handle</span><span class="o">&lt;&gt;</span> <span class="n">e_val</span><span class="p">(</span><span class="n">val</span><span class="p">),</span> <span class="n">e_type</span><span class="p">(</span><span class="n">type</span><span class="p">),</span> <span class="n">e_tb</span><span class="p">(</span><span class="n">allow_null</span><span class="p">(</span><span class="n">tb</span><span class="p">));</span> <span class="k">try</span> <span class="p">{</span> <span class="n">object</span> <span class="n">t</span> <span class="o">=</span> <span class="n">extract</span><span class="o">&lt;</span><span class="n">object</span><span class="o">&gt;</span><span class="p">(</span><span class="n">e_type</span><span class="p">.</span><span class="n">get</span><span class="p">());</span> <span class="n">object</span> <span class="n">t_name</span> <span class="o">=</span> <span class="n">t</span><span class="p">.</span><span class="n">attr</span><span class="p">(</span><span class="s">&quot;__name__&quot;</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">typestr</span> <span class="o">=</span> <span class="n">extract</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">t_name</span><span class="p">);</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="n">typestr</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">flush</span><span class="p">;</span> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">error_already_set</span> <span class="k">const</span> <span class="o">&amp;</span><span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Internal error getting error type:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span> <span class="n">PyErr_Print</span><span class="p">();</span> <span class="p">}</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;: &quot;</span><span class="p">;</span> <span class="k">try</span> <span class="p">{</span> <span class="n">object</span> <span class="n">v</span> <span class="o">=</span> <span class="n">extract</span><span class="o">&lt;</span><span class="n">object</span><span class="o">&gt;</span><span class="p">(</span><span class="n">e_val</span><span class="p">.</span><span class="n">get</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">valuestr</span> <span class="o">=</span> <span class="n">extract</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">v</span><span class="p">.</span><span class="n">attr</span><span class="p">(</span><span class="s">&quot;__str__&quot;</span><span class="p">)());</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="n">valuestr</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">flush</span><span class="p">;</span> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">error_already_set</span> <span class="k">const</span> <span class="o">&amp;</span><span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Internal error getting value type:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span> <span class="n">PyErr_Print</span><span class="p">();</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">tb</span><span class="p">)</span> <span class="p">{</span> <span class="k">try</span> <span class="p">{</span> <span class="n">object</span> <span class="n">tb_list</span> <span class="o">=</span> <span class="n">import</span><span class="p">(</span><span class="s">&quot;traceback&quot;</span><span class="p">).</span><span class="n">attr</span><span class="p">(</span><span class="s">&quot;format_tb&quot;</span><span class="p">)(</span><span class="n">e_tb</span><span class="p">);</span> <span class="n">object</span> <span class="n">tb_str</span> <span class="o">=</span> <span class="n">str</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">).</span><span class="n">attr</span><span class="p">(</span><span class="s">&quot;join&quot;</span><span class="p">)(</span><span class="n">tb_list</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span> <span class="o">=</span> <span class="n">extract</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">tb_str</span><span class="p">);</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">Traceback (recent call last):</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">str</span><span class="p">;</span> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">error_already_set</span> <span class="k">const</span> <span class="o">&amp;</span><span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Internal error getting traceback:</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span> <span class="n">PyErr_Print</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">os</span><span class="p">.</span><span class="n">str</span><span class="p">();</span> <span class="p">}</span> </pre></div></div><p> I'm sure it could be done better, but I'm sure this would help quite a bit. </p> <p> A wrapper for all python calls that translated python errors into C++-exceptions with proper contents would be very nice, but I can live with this. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2781 Trac 1.4.3 sohail-boost-trac@… Thu, 26 Nov 2009 22:40:51 GMT <link>https://svn.boost.org/trac10/ticket/2781#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2781#comment:1</guid> <description> <p> For me, it would be most useful if I could register an exception handling callback which allows me to throw my own exception when an error occurs in Python. This way, Python code can be called from C++ code just as if it is C++ code. Otherwise, we need to have boilerplate try/catch. </p> <p> For example, I'd like to write: </p> <pre class="wiki">void my_from_python_exception_handler() { throw MyException(pyerror_exctract&lt;My::String&gt;()); // don't hardcode above extract to std::string } void somewhere_in_the_app() { ... boost::python::register_from_python_exception_handler(my_from_python_exception_handler); } void somewhere_else_in_the_app() { cplusplus-&gt;call_python_code_directly_but_looks_like_cplusplus(); } </pre><p> Hope that helps. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>loonycyborg</dc:creator> <pubDate>Fri, 27 Nov 2009 13:50:42 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/2781#comment:2 https://svn.boost.org/trac10/ticket/2781#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">loonycyborg@…</span> added </li> </ul> Ticket rosebk Mon, 22 Jan 2018 06:34:57 GMT <link>https://svn.boost.org/trac10/ticket/2781#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2781#comment:3</guid> <description> <p> Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging… </p> <p> <a class="ext-link" href="https://www.besanttechnologies.com/training-courses/python-training-institute-in-bangalore"><span class="icon">​</span>https://www.besanttechnologies.com/training-courses/python-training-institute-in-bangalore</a> </p> </description> <category>Ticket</category> </item> </channel> </rss>