From 945919ffff7f4e856d17d2b5a6b48cab5417d92f Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 7 Nov 2006 23:18:56 +0000 Subject: Propagate libvirt errors back with python exceptions --- generator.py | 15 +++++++++++++-- libvir.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ libvir.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/generator.py b/generator.py index e973db1..5aa2625 100755 --- a/generator.py +++ b/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/libvir.c b/libvir.c index 3d580e5..a7b98dc 100644 --- a/libvir.c +++ b/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/libvir.py b/libvir.py index 29dc8c4..b0f0b2c 100644 --- a/libvir.py +++ b/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 -- cgit v1.2.1