Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > c3732731228538f6126cae930c10ad71 > files > 187

python-pyro4-4.21-3.mga4.noarch.rpm



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Errors and remote tracebacks &mdash; Pyro 4.21 documentation</title>
    
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '4.21',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Pyro 4.21 documentation" href="index.html" />
    <link rel="next" title="Flame: Foreign Location Automatic Module Exposer" href="flame.html" />
    <link rel="prev" title="Security" href="security.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="flame.html" title="Flame: Foreign Location Automatic Module Exposer"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="security.html" title="Security"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="errors-and-remote-tracebacks">
<h1>Errors and remote tracebacks<a class="headerlink" href="#errors-and-remote-tracebacks" title="Permalink to this headline">¶</a></h1>
<p>There is an example that shows various ways to deal with exceptions when writing Pyro code.
Have a look at the <tt class="docutils literal"><span class="pre">exceptions</span></tt> example in the <tt class="file docutils literal"><span class="pre">examples</span></tt> directory.</p>
<div class="section" id="pyro-errors">
<h2>Pyro errors<a class="headerlink" href="#pyro-errors" title="Permalink to this headline">¶</a></h2>
<p>Pyro&#8217;s exception classes can be found in <a class="reference internal" href="api/errors.html#module-Pyro4.errors" title="Pyro4.errors"><tt class="xref py py-mod docutils literal"><span class="pre">Pyro4.errors</span></tt></a>.
They are used by Pyro if something went wrong inside Pyro itself or related to something Pyro was doing.</p>
</div>
<div class="section" id="remote-errors">
<h2>Remote errors<a class="headerlink" href="#remote-errors" title="Permalink to this headline">¶</a></h2>
<p>More interesting are the errors that occur in <em>your own</em> objects (the remote Pyro objects).
Pyro is doing its best to make the remote objects appear as normal, local, Python objects.
That also means that if they raise an error, Pyro will make it appear in the caller,
as if the error occurred locally.</p>
<p>Say you have a remote object that can divide arbitrary numbers.
It will probably raise a <tt class="docutils literal"><span class="pre">ZeroDivisionError</span></tt> when you supply <tt class="docutils literal"><span class="pre">0</span></tt> as the divisor.
This can be dealt with as follows:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>

<span class="n">divider</span><span class="o">=</span><span class="n">Pyro4</span><span class="o">.</span><span class="n">Proxy</span><span class="p">(</span> <span class="o">...</span> <span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">divider</span><span class="o">.</span><span class="n">div</span><span class="p">(</span><span class="mi">999</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;yup, it crashed&quot;</span>
</pre></div>
</div>
<p>Just catch the exception as if you were writing code that deals with normal objects.</p>
<p>But, since the error occurred in a <em>remote</em> object, and Pyro itself raises it again on the client
side, you lose some information: the actual traceback of the error at the time it occurred in the server.
Pyro fixes this because it stores the traceback information on a special attribute on the exception
object (<tt class="docutils literal"><span class="pre">_pyroTraceback</span></tt>). The traceback is stored as a list of strings (each is a line from
the traceback text, including newlines). You can use this data on the client to print or process the
traceback text from the exception as it occurred in the Pyro object on the server.</p>
<p>There is a utility function in <a class="reference internal" href="api/util.html#module-Pyro4.util" title="Pyro4.util"><tt class="xref py py-mod docutils literal"><span class="pre">Pyro4.util</span></tt></a> to make it easy to deal with this:
<a class="reference internal" href="api/util.html#Pyro4.util.getPyroTraceback" title="Pyro4.util.getPyroTraceback"><tt class="xref py py-func docutils literal"><span class="pre">Pyro4.util.getPyroTraceback()</span></tt></a></p>
<p>You use it like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4.util</span>
<span class="k">try</span><span class="p">:</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">proxy</span><span class="o">.</span><span class="n">method</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Pyro traceback:&quot;</span>
    <span class="k">print</span> <span class="s">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">Pyro4</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">getPyroTraceback</span><span class="p">())</span>
</pre></div>
</div>
<p>Also, there is another function that you can install in <tt class="docutils literal"><span class="pre">sys.excepthook</span></tt>, if you want Python
to automatically print the complete Pyro traceback including the remote traceback, if any:
<a class="reference internal" href="api/util.html#Pyro4.util.excepthook" title="Pyro4.util.excepthook"><tt class="xref py py-func docutils literal"><span class="pre">Pyro4.util.excepthook()</span></tt></a></p>
<p>A full Pyro exception traceback, including the remote traceback on the server, looks something like this:</p>
<div class="highlight-python"><pre>Traceback (most recent call last):
  File "client.py", line 50, in &lt;module&gt;
    print(test.complexerror())     # due to the excepthook, the exception will show the pyro error
  File "E:\Projects\Pyro4\src\Pyro4\core.py", line 130, in __call__
    return self.__send(self.__name, args, kwargs)
  File "E:\Projects\Pyro4\src\Pyro4\core.py", line 242, in _pyroInvoke
    raise data
TypeError: unsupported operand type(s) for //: 'str' and 'int'
 +--- This exception occured remotely (Pyro) - Remote traceback:
 | Traceback (most recent call last):
 |   File "E:\Projects\Pyro4\src\Pyro4\core.py", line 760, in handleRequest
 |     data=method(*vargs, **kwargs)   # this is the actual method call to the Pyro object
 |   File "E:\projects\Pyro4\examples\exceptions\excep.py", line 17, in complexerror
 |     x.crash()
 |   File "E:\projects\Pyro4\examples\exceptions\excep.py", line 22, in crash
 |     s.crash2('going down...')
 |   File "E:\projects\Pyro4\examples\exceptions\excep.py", line 25, in crash2
 |     x=arg//2
 | TypeError: unsupported operand type(s) for //: 'str' and 'int'
 +--- End of remote traceback</pre>
</div>
<p>As you can see, the first part is only the exception as it occurs locally on the client (raised
by Pyro). The indented part marked with &#8216;Remote traceback&#8217; is the exception as it occurred
in the remote Pyro object.</p>
</div>
<div class="section" id="detailed-traceback-information">
<h2>Detailed traceback information<a class="headerlink" href="#detailed-traceback-information" title="Permalink to this headline">¶</a></h2>
<p>There is another utility that Pyro has to make it easier to debug remote object errors.
If you enable the <tt class="docutils literal"><span class="pre">DETAILED_TRACEBACK</span></tt> config item on the server (see <a class="reference internal" href="config.html#config-items"><em>Overview of Config Items</em></a>), the remote
traceback is extended with details of the values of the local variables in every frame:</p>
<div class="highlight-python"><pre>+--- This exception occured remotely (Pyro) - Remote traceback:
| ----------------------------------------------------
|  EXCEPTION &lt;type 'exceptions.TypeError'&gt;: unsupported operand type(s) for //: 'str' and 'int'
|  Extended stacktrace follows (most recent call last)
| ----------------------------------------------------
| File "E:\Projects\Pyro4\src\Pyro4\core.py", line 760, in Daemon.handleRequest
| Source code:
|     data=method(*vargs, **kwargs)   # this is the actual method call to the Pyro object
| ----------------------------------------------------
| File "E:\projects\Pyro4\examples\exceptions\excep.py", line 17, in TestClass.complexerror
| Source code:
|     x.crash()
| Local values:
|     self = &lt;excep.TestClass object at 0x02392830&gt;
|         self._pyroDaemon = &lt;Pyro4.core.Daemon object at 0x02392330&gt;
|         self._pyroId = 'obj_c63d47dd140f44dca8782151643e0c55'
|     x = &lt;excep.Foo object at 0x023929D0&gt;
| ----------------------------------------------------
| File "E:\projects\Pyro4\examples\exceptions\excep.py", line 22, in Foo.crash
| Source code:
|     self.crash2('going down...')
| Local values:
|     self = &lt;excep.Foo object at 0x023929D0&gt;
| ----------------------------------------------------
| File "E:\projects\Pyro4\examples\exceptions\excep.py", line 25, in Foo.crash2
| Source code:
|     x=arg//2
| Local values:
|     arg = 'going down...'
|     self = &lt;excep.Foo object at 0x023929D0&gt;
| ----------------------------------------------------
|  EXCEPTION &lt;type 'exceptions.TypeError'&gt;: unsupported operand type(s) for //: 'str' and 'int'
| ----------------------------------------------------
+--- End of remote traceback</pre>
</div>
<p>You can immediately see why the call produced a <tt class="docutils literal"><span class="pre">TypeError</span></tt> without the need to have a debugger running
(the <tt class="docutils literal"><span class="pre">arg</span></tt> variable is a string and dividing that string by 2 ofcourse is the cause of the error).</p>
<p>Ofcourse it is also possible to enable <tt class="docutils literal"><span class="pre">DETAILED_TRACEBACK</span></tt> on the client, but it is not as useful there
(normally it is no problem to run the client code inside a debugger).</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="index.html">
              <img class="logo" src="_static/pyro.png" alt="Logo"/>
            </a></p>
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Errors and remote tracebacks</a><ul>
<li><a class="reference internal" href="#pyro-errors">Pyro errors</a></li>
<li><a class="reference internal" href="#remote-errors">Remote errors</a></li>
<li><a class="reference internal" href="#detailed-traceback-information">Detailed traceback information</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="security.html"
                        title="previous chapter">Security</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="flame.html"
                        title="next chapter">Flame: Foreign Location Automatic Module Exposer</a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="flame.html" title="Flame: Foreign Location Automatic Module Exposer"
             >next</a> |</li>
        <li class="right" >
          <a href="security.html" title="Security"
             >previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright Irmen de Jong.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>