From: Daniel P. Berrange Date: Tue, 7 Nov 2006 23:18:56 +0000 (+0000) Subject: Propagate libvirt errors back with python exceptions X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e444b199dbff62407150be8ed2b8182163858ddf;p=people%2Fliuw%2Flibxenctrl-split%2Flibvirt.git Propagate libvirt errors back with python exceptions --- diff --git a/ChangeLog b/ChangeLog index 4cf4c9b7b..7cdbe4795 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Tue Nov 7 16:17:23 EDT 2006 Daniel P. Berrange + + * python/generator.py: Pass in connection object when generating + an exception + * python/libvir.py: Allow raw error object to be passed into the + python exception object. + * python/libvir.c: Added binding for virGetLastError and + virConnGetLastError + Tue Nov 7 15:58:43 EDT 2006 Daniel P. Berrange * src/xend_internal.c: Ensure that virConnectPtr object is passed diff --git a/python/generator.py b/python/generator.py index e973db193..5aa262554 100755 --- a/python/generator.py +++ b/python/generator.py @@ -260,6 +260,8 @@ foreign_encoding_args = ( # code is still automatically generated (so they are not in skip_function()). skip_impl = ( 'virConnectListDomainsID', + 'virConnGetLastError', + 'virGetLastError', 'virDomainGetInfo', 'virNodeGetInfo', 'virDomainGetUUID', @@ -869,9 +871,18 @@ def buildWrappers(): classes.write( " if ret is None:return None\n"); else: - classes.write( + if classname == "virConnect": + classes.write( + " if ret is None:raise libvirtError('%s() failed', conn=self)\n" % + (name)) + elif classname == "virDomain": + classes.write( + " if ret is None:raise libvirtError('%s() failed')\n" % + (name)) + else: + classes.write( " if ret is None:raise libvirtError('%s() failed')\n" % - (name)) + (name)) # # generate the returned class wrapper for the object diff --git a/python/libvir.c b/python/libvir.c index 3d580e584..a7b98dc00 100644 --- a/python/libvir.c +++ b/python/libvir.c @@ -18,6 +18,8 @@ void initlibvirmod(void); PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args); +PyObject *libvirt_virGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args); +PyObject *libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args); /************************************************************************ @@ -29,6 +31,62 @@ PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *ar static PyObject *libvirt_virPythonErrorFuncHandler = NULL; static PyObject *libvirt_virPythonErrorFuncCtxt = NULL; +PyObject * +libvirt_virGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) +{ + virError err; + PyObject *info; + + if (virCopyLastError(&err) <= 0) { + Py_INCREF(Py_None); + return(Py_None); + } + + info = PyTuple_New(9); + PyTuple_SetItem(info, 0, PyInt_FromLong((long) err.code)); + PyTuple_SetItem(info, 1, PyInt_FromLong((long) err.domain)); + PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err.message)); + PyTuple_SetItem(info, 3, PyInt_FromLong((long) err.level)); + PyTuple_SetItem(info, 4, libvirt_constcharPtrWrap(err.str1)); + PyTuple_SetItem(info, 5, libvirt_constcharPtrWrap(err.str2)); + PyTuple_SetItem(info, 6, libvirt_constcharPtrWrap(err.str3)); + PyTuple_SetItem(info, 7, PyInt_FromLong((long) err.int1)); + PyTuple_SetItem(info, 8, PyInt_FromLong((long) err.int2)); + + return info; +} + +PyObject * +libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) +{ + virError err; + PyObject *info; + virConnectPtr conn; + PyObject *pyobj_conn; + + if (!PyArg_ParseTuple(args, (char *)"O:virConGetLastError", &pyobj_conn)) + return(NULL); + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + if (virConnCopyLastError(conn, &err) <= 0) { + Py_INCREF(Py_None); + return(Py_None); + } + + info = PyTuple_New(9); + PyTuple_SetItem(info, 0, PyInt_FromLong((long) err.code)); + PyTuple_SetItem(info, 1, PyInt_FromLong((long) err.domain)); + PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err.message)); + PyTuple_SetItem(info, 3, PyInt_FromLong((long) err.level)); + PyTuple_SetItem(info, 4, libvirt_constcharPtrWrap(err.str1)); + PyTuple_SetItem(info, 5, libvirt_constcharPtrWrap(err.str2)); + PyTuple_SetItem(info, 6, libvirt_constcharPtrWrap(err.str3)); + PyTuple_SetItem(info, 7, PyInt_FromLong((long) err.int1)); + PyTuple_SetItem(info, 8, PyInt_FromLong((long) err.int2)); + + return info; +} + static void libvirt_virErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, virErrorPtr err) { @@ -311,6 +369,8 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL}, {(char *) "virDomainLookupByUUID", libvirt_virDomainLookupByUUID, METH_VARARGS, NULL}, {(char *) "virRegisterErrorHandler", libvirt_virRegisterErrorHandler, METH_VARARGS, NULL}, + {(char *) "virGetLastError", libvirt_virGetLastError, METH_VARARGS, NULL}, + {(char *) "virConnGetLastError", libvirt_virConnGetLastError, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; diff --git a/python/libvir.py b/python/libvir.py index 29dc8c41d..b0f0b2c1c 100644 --- a/python/libvir.py +++ b/python/libvir.py @@ -7,10 +7,63 @@ import libvirtmod import types -# The root of all libxml2 errors. +# The root of all libvirt errors. class libvirtError(Exception): - pass + def __init__(self, msg, conn=None): + Exception.__init__(self, msg) + if conn is None: + self.err = virGetLastError() + else: + self.err = conn.virConnGetLastError() + + def get_error_code(self): + if self.err is None: + return None + return self.err[0] + + def get_error_domain(self): + if self.err is None: + return None + return self.err[1] + + def get_error_message(self): + if self.err is None: + return None + return self.err[2] + + def get_error_level(self): + if self.err is None: + return None + return self.err[3] + + def get_str1(self): + if self.err is None: + return None + return self.err[4] + + def get_str2(self): + if self.err is None: + return None + return self.err[5] + + def get_str3(self): + if self.err is None: + return None + return self.err[6] + + def get_int1(self): + if self.err is None: + return None + return self.err[7] + + def get_int2(self): + if self.err is None: + return None + return self.err[8] + + def __str__(self): + return Exception.__str__(self) + " " + self.get_error_message() # # register the libvirt global error handler