On Mon, Nov 7, 2011 at 07:29, Gerhardus Geldenhuis <gerhardus.geldenhuis@gmail.com> wrote:
Hi

I get the following error:
xmlrpclib.Fault: <Fault 1: "cobbler.cexceptions.CX:'invalid profile name: rhel5u5-x86_64'">

I am still learning python so wanted to know is all errors always going to be the exception type 
xmlrpclib.Fault when using xmlrpc to interact with cobbler?

Secondly having grepped through the source code I found:
cobbler/item_system.py:        raise CX(_("invalid profile name: %s") % profile_name)

reason I did this was to get a list of possible error messages that I could expect. Would doing a 
grep 'raise CX' cobbler/item_system.py 
be a to simplistic approach to find these possible error messages?

A grep to find the error messages is a pretty good approach to finding them.
 
To try and answer my own question... maybe because it is xmlrpc and remote you will only get this generic error and if you were in the code (local) you get different exception classes... is there any point in recreating a list of exception classes to handle errors on the client side of the xmlrpc interface. Reason I ask is I am thinking that it might be cleaner to use the try except blocks rather than a bunch of if statements for strings but I am very open to opinions/guidance.

I think you are correct about being remote... so the question becomes what do you get if you inspect the xmlrpclib.Fault object?  In the case of above it is handing you the cobbler.cexceptions.CX exception class, tunneled through the xmlrpclib.Fault error.  Maybe with a bit of introspection you can pull these?

In [1]: import xmlrpclib

In [2]: server = xmlrpclib.Server("http://localhost/cobbler_api")

In [3]: try:
   ...:     token = server.login("username","password")
   ...: except xmlrpclib.Fault, e:
   ...:     pass
   ...:
In [4]: e.
e.__class__         e.__doc__           e.__getitem__       e.__init__          e.__reduce__        e.__setattr__       e.__str__           e.__weakref__       e.faultString      
e.__delattr__       e.__format__        e.__getslice__      e.__module__        e.__reduce_ex__     e.__setstate__      e.__subclasshook__  e.args              e.message          
e.__dict__          e.__getattribute__  e.__hash__          e.__new__           e.__repr__          e.__sizeof__        e.__unicode__       e.faultCode        

In [4]: e.faultCode
Out[4]: 1

In [5]: e.faultString
Out[5]: "<class 'cobbler.cexceptions.CX'>:'login failed (username)'"

So... unfortunately that doesn't look like its passing it along as more than a string.. however:

In [10]: ex, message = e.faultString.replace("'","").split(":")

In [11]: ex
Out[11]: '<class cobbler.cexceptions.CX>'

In [12]: message
Out[12]: 'login failed (username)'

In [13]: if 'cobbler.cexceptions.CX' in ex:
   ....:     print message
login failed (username)


So if you were making this a backend portion of your code in a library you could do something like this (maybe):

import xmlrpclib
from cobbler import cexceptions

server = xmlrpclib.Server("http://remote/cobbler_api")
try:
    token = server.login("username", "password")
except xmlrpclib.Fault, e:
    if 'cobbler.cexceptions.CX' in e.faultString:
         message = e.faultString.replace("'","").split(":")[-1]
         raise cexecceptions.CS(message)
    else:
        raise xmlrpclib.Fault(e.faultString)


I'm not 100% on this idea, and its definately not perfect, but *shrug* I adjusted my grep of all the errors and non of them contain a single quot or colon, so that should be a fairly safe replace and split process.  If anyone has a better path for Gerhardus, please chime in :)