[Zope-dev] ZPublisher XMLRPC extension for user exceptions

Illarramendi Amilibia, Aitor aillarramendi@indra.es
Thu, 27 Feb 2003 17:13:38 +0100


This is a multi-part message in MIME format.

------_=_NextPart_001_01C2DE7B.2FEE5FD4
Content-Type: multipart/alternative;
	boundary="----_=_NextPart_002_01C2DE7B.2FEE5FD4"


------_=_NextPart_002_01C2DE7B.2FEE5FD4
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hello everybody:
=20
    I'm making some kind of development related to invoke externally =
from a Java Applet some ZOPE product methods via XML-RPC.
=20
    I use ZOPE as the XMLRPC server, as it can 'listen' for XMLRPC =
requests, find the method requested using URL and traversal, invoke the =
method and receive the return value of it and then encapsulate the =
result in a XMLRPC response.
=20
    Anyways, I want to report some exceptions from my ZOPE product =
python methods through XML-RPC to the applet. As my methods don't work =
directly with XMLRPC, all is embedded inside ZOPE, all the XMLRPC works =
are transparent for my python methods, so I didn't realize how I could =
do it.
=20
    After looking for the ZOPE code responsible of the XMLRPC request =
process and XMLRPC response generation I found that some of the work was =
being done in ZPublisher xmlrpc.py code (Response stuff).
=20
    Then when I started to read the comments of the code I found this in =
the Response class of the code:
=20
            """ It's probably possible to improve the 'exception' method =
quite a bit. The current implementation, however, should suffice for =
now. """
=20
    But as you will see is not enough, at least for my needs.
=20
    I want to define my own exceptions in my product, this exceptions =
could be defined as follows:
=20
        class MyOwnException:
            __init__(self, faultCode, faultString):
                self.faultCode =3D faultCode
                self.faultString =3D faultString
=20
        Obviously I want to map XMLRPC-like fault format.
=20
        Then, I could raise this exception from my method, and I will =
want that the class responsible of making the XMLRPC Response for my =
XMLRPC client will use it for composing the XML for XMLRPC using my =
fault code and fault string.
=20
        But I found that xmlrpc.py doesn't take into account that (i'm =
talking of ZOPE 2.6.0) so i had to make some changes in the code of =
ZPublisher/xmlrpc.py:
=20
            def exception(self, fatal=3D0, info=3DNone,
                  absuri_match=3DNone, tag_search=3DNone):
                  # Fetch our exception info. t is type, v is value and =
tb is the
                  # traceback object.
                  if type(info) is type(()) and len(info)=3D=3D3: t,v,tb =
=3D info
                  else:=20
                      t,v,tb =3D sys.exc_info()
 =20
                  # Don't mask 404 respnses, as some XML-RPC libraries =
rely on the HTTP
                  # mechanisms for detecting when authentication is =
required. Fixes Zope
                  # Collector issue 525.
                  if t =3D=3D 'Unauthorized' or (isinstance(t, =
types.ClassType)
                                   and issubclass(t, Unauthorized)):
                    return self._real.exception(fatal=3Dfatal, =
info=3Dinfo)
=20
                  # Create an appropriate Fault object. Containing error =
information
                  Fault=3Dxmlrpclib.Fault
                  f=3DNone
                  try:
                    # Strip HTML tags from the error value
                    v =3D str(v)
                    remove =3D [r"<[^<>]*>", r"&[A-Za-z]+;"]
                    for pat in remove:
                        v =3D re.sub(pat, " ", v)
                        from Globals import DevelopmentMode
                        if DevelopmentMode:
                            from traceback import format_exception
                            value =3D '\n' + ''.join(format_exception(t, =
v, tb))
                        else:
                            value =3D '%s - %s' % (t, v)
               =20
                        ######  my own extension for catching user =
exceptions START #####
                        try:
                          faultCode =3D =
getattr(sys.exc_info()[1],'faultCode')
                          faultString =3D =
getattr(sys.exc_info()[1],'faultString')
                        except:
                          print "no according exception type"
                        ######  my own extension for catching user =
exceptions FINISH #####
                        if isinstance(v, Fault):
                            f=3Dv=20
                        ###### my own extension for catching user =
exceptions START #####
                        elif (faultCode and faultString) :
                            f =3D xmlrpclib.Fault(faultCode,faultString)
                        ###### my own extension for catching user =
exceptions FINISH ######
                        elif isinstance(v, Exception):
                            f=3DFault(-1, 'Unexpected Zope exception: =
%s' % value)
                        else:
                            f=3DFault(-2, 'Unexpected Zope error value: =
%s' % value)
                  except:
                      f=3DFault(-3, "Unknown Zope fault type")
=20
                  # Do the damage.
                  self.setBody(f)
                  self._real.setStatus(200)
=20
                  return tb
=20
        By that way, I could send my own fault code and fault =
descriptions via XML-RPC.
=20
        But as you can see, I have to extend ZOPE code, and I don't want =
to do it, I have to work with standard releases of ZOPE.
=20
        Do you think that something like that would be improved in an =
early future for next ZOPE releases?
=20
        Any opinion will be really appreciated.
=20
        Thanks for advance.
=20
Regards.
=20
	Aitor Illarramendi Amilibia=09
 	=20
Ingeniero de software
Mando y Control=20
 <http://www.indra.es/>  Indra.bmp=09
 	=20
Carretera de Loeches, 9
28850 - Torrej=F3n de Ardoz, Madrid (ESPA=D1A)
Tel: +34-91-626.80.60
Fax: +34-91-626.81.14
aillarramendi@indra.es
www.indra.es <http://www.indra.es/>=20

=20

------_=_NextPart_002_01C2DE7B.2FEE5FD4
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Diso-8859-1">


<META content=3D"MSHTML 5.50.4134.600" name=3DGENERATOR></HEAD>
<BODY>
<DIV><FONT face=3DArial size=3D2><SPAN class=3D538114715-27022003>Hello=20
everybody:</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;=20
I'm making some kind of development related to invoke externally from a =
Java=20
Applet some ZOPE product methods via XML-RPC.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp; I=20
use ZOPE as the XMLRPC server, as it can 'listen' for XMLRPC requests, =
find the=20
method requested using URL and traversal, invoke the method and receive =
the=20
return value of it and then encapsulate the result in a XMLRPC=20
response.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;=20
Anyways, I want to report some exceptions from my ZOPE product python =
methods=20
through XML-RPC to the applet. As my methods don't work directly with =
XMLRPC,=20
all is embedded inside ZOPE, all the XMLRPC works are transparent for my =
python=20
methods, so&nbsp;I didn't realize how&nbsp;I could do =
it.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;=20
After looking for the ZOPE code responsible of the XMLRPC request =
process and=20
XMLRPC response generation I found that some of the work was being done =
in=20
ZPublisher xmlrpc.py code (Response stuff).</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;=20
Then when&nbsp;I started to read the comments of the code I found this =
in the=20
Response class of the code:</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;=20
""" It's probably possible to improve the 'exception' method quite a =
bit. The=20
current implementation, however, should suffice for now. =
"""</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;=20
But as you will see is not enough, at least for my =
needs.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN =
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp; I=20
want to define my own exceptions in my product, this exceptions could be =
defined=20
as follows:</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
class=20
MyOwnException:</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;=20
__init__(self, faultCode, faultString):</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
self.faultCode =3D faultCode</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
self.faultString =3D faultString</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Obviously I=20
want to map XMLRPC-like fault format.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Then, I=20
could raise this exception from my method, and I will want that the =
class=20
responsible of making the XMLRPC Response for my XMLRPC client will use =
it for=20
composing the XML for XMLRPC using my fault code and fault=20
string.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
But I found=20
that xmlrpc.py doesn't take into account that (i'm talking of ZOPE =
2.6.0) so i=20
had to make some changes in the code of=20
ZPublisher/xmlrpc.py:</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;=20
<FONT face=3D"Times New Roman" color=3D#ff0000 size=3D1>def =
exception(self, fatal=3D0,=20
info=3DNone,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
absuri_match=3DNone,=20
tag_search=3DNone):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#=20
Fetch our exception info. t is type, v is value and tb is=20
the<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
# traceback=20
object.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
if type(info) is type(()) and len(info)=3D=3D3: t,v,tb =3D=20
info<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
else:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
t,v,tb =3D=20
sys.exc_info()<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#=20
Don't mask 404 respnses, as some XML-RPC libraries rely on the=20
HTTP<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
# mechanisms for detecting when authentication is required. Fixes=20
Zope<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
# Collector issue=20
525.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
if t =3D=3D 'Unauthorized' or (isinstance(t,=20
types.ClassType)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;=20
and issubclass(t,=20
Unauthorized)):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
return self._real.exception(fatal=3Dfatal, =
info=3Dinfo)</FONT></SPAN></FONT></DIV>
<DIV><FONT color=3D#ff0000 size=3D1></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#ff0000 size=3D1><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#=20
Create an appropriate Fault object. Containing error=20
information<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
Fault=3Dxmlrpclib.Fault<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f=3DNone<BR=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
try:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
# Strip HTML tags from the error=20
value<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
v =3D=20
str(v)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
remove =3D [r"&lt;[^&lt;&gt;]*&gt;",=20
r"&amp;[A-Za-z]+;"]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
for pat in=20
remove:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;=20
v =3D re.sub(pat, " ",=20
v)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
from Globals import=20
DevelopmentMode<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;=20
if=20
DevelopmentMode:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
from traceback import=20
format_exception<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
value =3D '\n' + ''.join(format_exception(t, v,=20
tb))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
=20
else:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;=20
value =3D '%s - %s' % (t,=20
v)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT=20
color=3D#0000ff>######&nbsp; my own extension for catching user =
exceptions=20
START&nbsp;#####<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;=20
try:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;=20
faultCode =3D=20
getattr(sys.exc_info()[1],'faultCode')<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
faultString =3D=20
getattr(sys.exc_info()[1],'faultString')<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except:<BR>&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
print "no&nbsp;according exception=20
type"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;######&nbsp;=20
my own extension for catching user exceptions&nbsp;FINISH=20
#####</FONT></SPAN></FONT><FONT color=3D#ff0000 size=3D1></FONT></DIV>
<DIV><FONT color=3D#ff0000 size=3D1><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;if=20
isinstance(v,=20
Fault):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;=20
f=3Dv&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;<FONT=20
color=3D#0000ff>###### my own extension for catching user exceptions =
START=20
#####<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;elif=20
(faultCode and faultString)=20
:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;=20
f =3D=20
xmlrpclib.Fault(faultCode,faultString)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;######=20
my own extension for catching user exceptions&nbsp;FINISH=20
######<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;=20
elif isinstance(v,=20
Exception):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
f=3DFault(-1, 'Unexpected Zope exception: %s' %=20
value)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;=20
else:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;=20
f=3DFault(-2, 'Unexpected Zope error value: %s' %=20
value)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except:<BR>&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f=3DFault(-3,=20
"Unknown Zope fault type")</SPAN></FONT></DIV>
<DIV><FONT color=3D#ff0000 size=3D1></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#ff0000 size=3D1><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#=20
Do the=20
damage.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.setBody(f)<BR>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;self._real.setStatus(200)</SPAN></FONT></DIV>
<DIV><FONT color=3D#ff0000 size=3D1></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#ff0000 size=3D1><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
return tb</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; By =
that way,=20
I could send my own fault code and fault descriptions via=20
XML-RPC.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
But as you=20
can see, I have to extend ZOPE code, and I don't want to do it, I have =
to work=20
with standard releases of ZOPE.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Do =
you think=20
that something like that would be improved in an early future for next =
ZOPE=20
releases?</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Any opinion=20
will be really appreciated.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Thanks for=20
advance.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003>Regards.</SPAN></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><SPAN=20
class=3D538114715-27022003></SPAN></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>
<TABLE style=3D"WIDTH: 500px" width=3D500 border=3D0>
  <TBODY>
  <TR>
    <TD width=3D40></TD>
    <TD=20
    style=3D"FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: navy; =
FONT-FAMILY: Verdana"=20
    vAlign=3Dcenter>Aitor Illarramendi Amilibia</TD></TR>
  <TR>
    <TD width=3D40>&nbsp;</TD>
    <TD=20
    style=3D"FONT-WEIGHT: bold; FONT-SIZE: 10px; COLOR: navy; =
FONT-FAMILY: Verdana"=20
    vAlign=3Dcenter>
      <DIV>Ingeniero de software</DIV>
      <DIV>Mando y Control </DIV></TD></TR>
  <TR>
    <TD style=3D"HEIGHT: 20px" vAlign=3Dcenter width=3D100 =
colSpan=3D2><A=20
      href=3D"http://www.indra.es/"></A>&nbsp;<IMG alt=3DIndra.bmp =
hspace=3D0=20
      src=3D"cid:538114715@27022003-18e0" align=3Dbaseline =
border=3D0></TD></TR>
  <TR>
    <TD width=3D40>&nbsp;</TD>
    <TD=20
    style=3D"FONT-WEIGHT: bold; FONT-SIZE: 10px; COLOR: navy; =
FONT-FAMILY: Verdana"=20
    vAlign=3Dtop>
      <DIV>Carretera de Loeches, 9<BR>28850 - Torrej=F3n de Ardoz, =
Madrid=20
      (ESPA=D1A)<BR>Tel: +34-91-626.80.60<BR>Fax: +34-91-626.81.14</DIV>
      <DIV><A=20
      =
href=3D"mailto:aillarramendi@indra.es">aillarramendi@indra.es</A><BR><A=20
      =
href=3D"http://www.indra.es/">www.indra.es</A><BR></DIV></TD></TR></TBODY=
></TABLE></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV></BODY></HTML>

------_=_NextPart_002_01C2DE7B.2FEE5FD4--

------_=_NextPart_001_01C2DE7B.2FEE5FD4
Content-Type: image/bmp;
	name="Indra.bmp"
Content-Transfer-Encoding: base64
Content-ID: <538114715@27022003-18e0>
Content-Description: Indra.bmp
Content-Location: Indra.bmp

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
AA==

------_=_NextPart_001_01C2DE7B.2FEE5FD4--