[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Ovirt-devel] [patch] Even Better Exceptions For ruby-libvirt bindings



Updated and attached. Good news is everything compiles fine and everything seems to work. Due to request, I did not add the libvirt exception structure to the ruby-libvirt exception object, rather the message field is copied over. For the next revision the code, domain, level, other message fields, and anything else anyone needs will also be included. Enjoy!


diff -r de489d66999d ext/libvirt/_libvirt.c
--- a/ext/libvirt/_libvirt.c	Mon Mar 31 10:00:40 2008 -0700
+++ b/ext/libvirt/_libvirt.c	Tue Apr 01 12:52:49 2008 -0400
@@ -17,15 +17,17 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  *
- * Author: David Lutterkort <dlutter redhat com>
+ * Authors: David Lutterkort <dlutter redhat com>, Mohammed Morsi <mmorsi redhat com>
  */
 
 #include <ruby.h>
 #include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
 #include "extconf.h"
 
 static VALUE m_libvirt;
 static VALUE c_connect;
+static VALUE c_vir_error;
 static VALUE c_domain;
 static VALUE c_domain_info;
 #if HAVE_TYPE_VIRNETWORKPTR
@@ -41,6 +43,14 @@ static VALUE c_storage_vol;
 static VALUE c_storage_vol;
 static VALUE c_storage_vol_info;
 #endif
+
+
+// define additional errors here
+static VALUE e_Error;                   // Error - generic error
+static VALUE e_ConnectionError;         // ConnectionError - error durring connection establishment
+static VALUE e_DefinitionError;         // DefinitionError - error during data definition
+static VALUE e_RetrieveError;           // RetrievalError - error during data retrieval
+static VALUE e_OperationError;          // OperationError - error during other various operations
 
 /*
  * Internal helpers
@@ -111,6 +121,22 @@ static virConnectPtr conn(VALUE s) {
     return conn;
 }
 
+/* Errors */
+static VALUE create_error(VALUE error, char* method, char* msg, 
+                                virConnectPtr conn){
+    extern VALUE ruby_errinfo;
+    int result;
+    virError err;
+
+    ruby_errinfo = rb_exc_new2(error, msg);
+    rb_iv_set(ruby_errinfo, "@libvirt_function_name", rb_str_new2(method));
+    
+    result = (conn == NULL ? virCopyLastError(&err) : virConnCopyLastError(conn, &err));
+    if(result >= 0) rb_iv_set(ruby_errinfo, "@vir_error", rb_str_new2(err.message));
+
+    return ruby_errinfo;
+};
+
 /* Domains */
 static void domain_free(void *d) {
     generic_free(Domain, d);
@@ -170,13 +196,13 @@ static VALUE vol_new(virStorageVolPtr n,
 #endif
 
 /* Error handling */
-#define _E(cond, conn, fn) \
-    do { if (cond) vir_error(conn, fn); } while(0)
-
-NORETURN(static void vir_error(virConnectPtr conn, const char *fn));
-
-static void vir_error(virConnectPtr conn, const char *fn) {
-    rb_raise(rb_eSystemCallError, "libvir call %s failed", fn);
+#define _E(cond, excep) \
+    do { if (cond) vir_error(excep); } while(0)
+ 
+NORETURN(static void vir_error(VALUE exception));
+ 
+static void vir_error(VALUE exception) {
+    rb_exc_raise(exception);
 }
 
 /*
@@ -197,7 +223,7 @@ static void vir_error(virConnectPtr conn
         virConnectPtr conn = connect_get(c);                            \
                                                                         \
         result = virConnectNumOf##objs(conn);                           \
-        _E(result < 0, conn, "virConnectNumOf" # objs);               \
+        _E(result < 0, create_error(e_RetrieveError, "virConnectNumOf" # objs, "", conn));                \
                                                                         \
         return INT2NUM(result);                                         \
     } while(0)
@@ -216,13 +242,13 @@ static void vir_error(virConnectPtr conn
         VALUE result;                                                   \
                                                                         \
         num = virConnectNumOf##objs(conn);                              \
-        _E(num < 0, conn, "virConnectNumOf" # objs);                  \
+        _E(num < 0, create_error(e_RetrieveError, "virConnectNumOf" # objs, "", conn));   \
                                                                         \
         names = ALLOC_N(char *, num);                                   \
         r = virConnectList##objs(conn, names, num);                     \
         if (r < 0) {                                                    \
             free(names);                                                \
-            _E(r < 0, conn, "virConnectList" # objs);                   \
+            _E(r < 0, create_error(e_RetrieveError, "virConnectList" # objs, "", conn));  \
         }                                                               \
                                                                         \
         result = rb_ary_new2(num);                                      \
@@ -242,7 +268,7 @@ static void vir_error(virConnectPtr conn
     do {                                                                \
         int _r_##func;                                                  \
         _r_##func = func(args);                                         \
-        _E(_r_##func < 0, conn, #func);                               \
+        _E(_r_##func < 0, create_error(e_Error, #func, "", conn));                        \
         return Qnil;                                                    \
     } while(0)
 
@@ -256,7 +282,7 @@ static void vir_error(virConnectPtr conn
         VALUE result;                                                   \
                                                                         \
         str = func(args);                                               \
-        _E(str == NULL, conn, # func);                                  \
+        _E(str == NULL, create_error(e_Error, # func, "", conn));                         \
                                                                         \
         result = rb_str_new2(str);                                      \
         if (dealloc)                                                    \
@@ -336,7 +362,7 @@ VALUE libvirt_open_read_only(VALUE m, VA
             rb_raise(rb_eTypeError, "expected string");
     }
     virConnectPtr ptr = virConnectOpenReadOnly(str);
-    _E(!ptr, NULL, "virConnectOpenReadOnly");
+    _E(!ptr, create_error(e_ConnectionError, "virConnectOpenReadOnly", "", NULL));
 
     return connect_new(ptr);
 }
@@ -396,7 +422,7 @@ VALUE libvirt_conn_version(VALUE s) {
     virConnectPtr conn = connect_get(s);
 
     r = virConnectGetVersion(conn, &v);
-    _E(r < 0, conn, "virConnectGetVersion");
+    _E(r < 0, create_error(e_RetrieveError, "virConnectGetVersion", "", conn));
 
     return ULONG2NUM(v);
 }
@@ -429,7 +455,7 @@ VALUE libvirt_conn_max_vcpus(VALUE s, VA
     virConnectPtr conn = connect_get(s);
 
     result = virConnectGetMaxVcpus(conn, StringValueCStr(type));
-    _E(result < 0, conn, "virConnectGetMaxVcpus");
+    _E(result < 0, create_error(e_RetrieveError, "virConnectGetMaxVcpus", "", conn));
 
     return INT2NUM(result);
 }
@@ -445,7 +471,7 @@ VALUE libvirt_conn_node_get_info(VALUE s
     VALUE modelstr;
 
     r = virNodeGetInfo(conn, &nodeinfo);
-    _E(r < 0, conn, "virNodeGetInfo");
+    _E(r < 0, create_error(e_RetrieveError, "virNodeGetInfo", "", conn));
 
     modelstr = rb_str_new2(nodeinfo.model);
 
@@ -486,13 +512,13 @@ VALUE libvirt_conn_list_domains(VALUE s)
     VALUE result;
 
     num = virConnectNumOfDomains(conn);
-    _E(num < 0, conn, "virConnectNumOfDomains");
+    _E(num < 0, create_error(e_RetrieveError, "virConnectNumOfDomains", "", conn));
 
     ids = ALLOC_N(int, num);
     r = virConnectListDomains(conn, ids, num);
     if (r < 0) {
         free(ids);
-        _E(r < 0, conn, "virConnectListDomains");
+        _E(r < 0, create_error(e_RetrieveError, "virConnectListDomains", "", conn));
     }
 
     result = rb_ary_new2(num);
@@ -660,7 +686,7 @@ VALUE libvirt_dom_info(VALUE s) {
     VALUE result;
 
     r = virDomainGetInfo(dom, &info);
-    _E(r < 0, conn(s), "virDomainGetInfo");
+    _E(r < 0, create_error(e_RetrieveError, "virDomainGetInfo", "", conn(s)));
 
     result = rb_class_new_instance(0, NULL, c_domain_info);
     rb_iv_set(result, "@state", CHR2FIX(info.state));
@@ -688,7 +714,7 @@ VALUE libvirt_dom_id(VALUE s) {
     unsigned int id;
 
     id = virDomainGetID(dom);
-    _E(id < 0, conn(s), "virDomainGetID");
+    _E(id < 0, create_error(e_RetrieveError, "virDomainGetID", "", conn(s)));
 
     return UINT2NUM(id);
 }
@@ -702,7 +728,7 @@ VALUE libvirt_dom_uuid(VALUE s) {
     int r;
 
     r = virDomainGetUUIDString(dom, uuid);
-    _E(r < 0, conn(s), "virDomainGetUUIDString");
+    _E(r < 0, create_error(e_RetrieveError, "virDomainGetUUIDString", "", conn(s)));
 
     return rb_str_new2((char *) uuid);
 }
@@ -723,7 +749,7 @@ VALUE libvirt_dom_max_memory(VALUE s) {
     unsigned long max_memory;
 
     max_memory = virDomainGetMaxMemory(dom);
-    _E(max_memory == 0, conn(s), "virDomainGetMaxMemory");
+    _E(max_memory == 0, create_error(e_RetrieveError, "virDomainGetMaxMemory", "", conn(s)));
 
     return ULONG2NUM(max_memory);
 }
@@ -736,7 +762,7 @@ VALUE libvirt_dom_max_memory_set(VALUE s
     int r;
 
     r = virDomainSetMaxMemory(dom, NUM2ULONG(max_memory));
-    _E(r < 0, conn(s), "virDomainSetMaxMemory");
+    _E(r < 0, create_error(e_DefinitionError, "virDomainSetMaxMemory", "", conn(s)));
 
     return ULONG2NUM(max_memory);
 }
@@ -749,7 +775,7 @@ VALUE libvirt_dom_memory_set(VALUE s, VA
     int r;
 
     r = virDomainSetMemory(dom, NUM2ULONG(memory));
-    _E(r < 0, conn(s), "virDomainSetMemory");
+    _E(r < 0, create_error(e_DefinitionError, "virDomainSetMemory", "", conn(s)));
 
     return ULONG2NUM(memory);
 }
@@ -762,7 +788,7 @@ VALUE libvirt_dom_max_vcpus(VALUE s) {
     int vcpus;
 
     vcpus = virDomainGetMaxVcpus(dom);
-    _E(vcpus < 0, conn(s), "virDomainGetMaxVcpus");
+    _E(vcpus < 0, create_error(e_RetrieveError, "virDomainGetMaxVcpus", "", conn(s)));
 
     return INT2NUM(vcpus);
 }
@@ -776,7 +802,7 @@ VALUE libvirt_dom_vcpus_set(VALUE s, VAL
     int r;
 
     r = virDomainSetVcpus(dom, NUM2UINT(nvcpus));
-    _E(r < 0, conn(s), "virDomainSetVcpus");
+    _E(r < 0, create_error(e_DefinitionError, "virDomainSetVcpus", "", conn(s)));
 
     return r;
 }
@@ -792,7 +818,7 @@ VALUE libvirt_dom_pin_vcpu(VALUE s, VALU
     virConnectPtr c = conn(s);
 
     r = virNodeGetInfo(c, &nodeinfo);
-    _E(r < 0, c, "virNodeGetInfo");
+    _E(r < 0, create_error(e_RetrieveError, "virNodeGetInfo", "", c));
 
     maplen = VIR_CPU_MAPLEN(nodeinfo.cpus);
     cpumap = ALLOC_N(unsigned char, maplen);
@@ -806,7 +832,7 @@ VALUE libvirt_dom_pin_vcpu(VALUE s, VALU
 
     r = virDomainPinVcpu(dom, NUM2UINT(vcpu), cpumap, maplen);
     free(cpumap);
-    _E(r < 0, c, "virDomainPinVcpu");
+    _E(r < 0, create_error(e_RetrieveError, "virDomainPinVcpu", "", c));
 
     return r;
 }
@@ -844,7 +870,7 @@ VALUE libvirt_dom_autostart(VALUE s){
     int r, autostart;
 
     r = virDomainGetAutostart(dom, &autostart);
-    _E(r < 0, conn(s), "virDomainAutostart");
+    _E(r < 0, create_error(e_RetrieveError, "virDomainAutostart", "", conn(s)));
 
     return autostart ? Qtrue : Qfalse;
 }
@@ -868,7 +894,7 @@ VALUE libvirt_conn_create_linux(VALUE c,
     xmlDesc = StringValueCStr(xml);
 
     dom = virDomainCreateLinux(conn, xmlDesc, NUM2UINT(flags));
-    _E(dom == NULL, conn, "virDomainCreateLinux");
+    _E(dom == NULL, create_error(e_OperationError, "virDomainCreateLinux", "", conn));
 
     return domain_new(dom, c);
 }
@@ -881,7 +907,7 @@ VALUE libvirt_conn_lookup_domain_by_name
     virConnectPtr conn = connect_get(c);
 
     dom = virDomainLookupByName(conn, StringValueCStr(name));
-    _E(dom == NULL, conn, "virDomainLookupByName");
+    _E(dom == NULL, create_error(e_RetrieveError, "virDomainLookupByName", "", conn));
 
     return domain_new(dom, c);
 }
@@ -894,7 +920,7 @@ VALUE libvirt_conn_lookup_domain_by_id(V
     virConnectPtr conn = connect_get(c);
 
     dom = virDomainLookupByID(conn, NUM2INT(id));
-    _E(dom == NULL, conn, "virDomainLookupByID");
+    _E(dom == NULL, create_error(e_RetrieveError, "virDomainLookupByID", "", conn));
 
     return domain_new(dom, c);
 }
@@ -907,7 +933,7 @@ VALUE libvirt_conn_lookup_domain_by_uuid
     virConnectPtr conn = connect_get(c);
 
     dom = virDomainLookupByUUIDString(conn, StringValueCStr(uuid));
-    _E(dom == NULL, conn, "virDomainLookupByUUID");
+    _E(dom == NULL, create_error(e_RetrieveError, "virDomainLookupByUUID", "", conn));
 
     return domain_new(dom, c);
 }
@@ -920,7 +946,7 @@ VALUE libvirt_conn_define_domain_xml(VAL
     virConnectPtr conn = connect_get(c);
 
     dom = virDomainDefineXML(conn, StringValueCStr(xml));
-    _E(dom == NULL, conn, "virDomainDefineXML");
+    _E(dom == NULL, create_error(e_DefinitionError, "virDomainDefineXML", "", conn));
 
     return domain_new(dom, c);
 }
@@ -938,7 +964,7 @@ VALUE libvirt_conn_lookup_network_by_nam
     virConnectPtr conn = connect_get(c);
 
     netw = virNetworkLookupByName(conn, StringValueCStr(name));
-    _E(netw == NULL, conn, "virNetworkLookupByName");
+    _E(netw == NULL, create_error(e_RetrieveError, "virNetworkLookupByName", "", conn));
 
     return network_new(netw, c);
 }
@@ -951,7 +977,7 @@ VALUE libvirt_conn_lookup_network_by_uui
     virConnectPtr conn = connect_get(c);
 
     netw = virNetworkLookupByUUIDString(conn, StringValueCStr(uuid));
-    _E(netw == NULL, conn, "virNetworkLookupByUUID");
+    _E(netw == NULL, create_error(e_RetrieveError, "virNetworkLookupByUUID", "", conn));
 
     return network_new(netw, c);
 }
@@ -967,7 +993,7 @@ VALUE libvirt_conn_create_network_xml(VA
     xmlDesc = StringValueCStr(xml);
 
     netw = virNetworkCreateXML(conn, xmlDesc);
-    _E(netw == NULL, conn, "virNetworkCreateXML");
+    _E(netw == NULL, create_error(e_OperationError, "virNetworkCreateXML", "", conn));
 
     return network_new(netw, c);
 }
@@ -980,7 +1006,7 @@ VALUE libvirt_conn_define_network_xml(VA
     virConnectPtr conn = connect_get(c);
 
     netw = virNetworkDefineXML(conn, StringValueCStr(xml));
-    _E(netw == NULL, conn, "virNetworkDefineXML");
+    _E(netw == NULL, create_error(e_DefinitionError, "virNetworkDefineXML", "", conn));
 
     return network_new(netw, c);
 }
@@ -1028,7 +1054,7 @@ VALUE libvirt_netw_uuid(VALUE s) {
     int r;
 
     r = virNetworkGetUUIDString(netw, uuid);
-    _E(r < 0, conn(s), "virNetworkGetUUIDString");
+    _E(r < 0, create_error(e_RetrieveError, "virNetworkGetUUIDString", "", conn(s)));
 
     return rb_str_new2((char *) uuid);
 }
@@ -1057,7 +1083,7 @@ VALUE libvirt_netw_autostart(VALUE s){
     int r, autostart;
 
     r = virNetworkGetAutostart(netw, &autostart);
-    _E(r < 0, conn(s), "virNetworkAutostart");
+    _E(r < 0, create_error(e_RetrieveError, "virNetworkAutostart", "", conn(s)));
 
     return autostart ? Qtrue : Qfalse;
 }
@@ -1084,7 +1110,7 @@ VALUE libvirt_conn_lookup_pool_by_name(V
     virConnectPtr conn = connect_get(c);
 
     pool = virStoragePoolLookupByName(conn, StringValueCStr(name));
-    _E(pool == NULL, conn, "virStoragePoolLookupByName");
+    _E(pool == NULL, create_error(e_RetrieveError, "virStoragePoolLookupByName", "", conn));
 
     return pool_new(pool, c);
 }
@@ -1097,7 +1123,7 @@ VALUE libvirt_conn_lookup_pool_by_uuid(V
     virConnectPtr conn = connect_get(c);
 
     pool = virStoragePoolLookupByUUIDString(conn, StringValueCStr(uuid));
-    _E(pool == NULL, conn, "virStoragePoolLookupByUUID");
+    _E(pool == NULL, create_error(e_RetrieveError, "virStoragePoolLookupByUUID", "", conn));
 
     return pool_new(pool, c);
 }
@@ -1109,7 +1135,7 @@ VALUE libvirt_vol_get_pool(VALUE v) {
     virStoragePoolPtr pool;
 
     pool = virStoragePoolLookupByVolume(vol_get(v));
-    _E(pool == NULL, conn(v), "virStoragePoolLookupByVolume");
+    _E(pool == NULL, create_error(e_RetrieveError, "virStoragePoolLookupByVolume", "", conn(v)));
 
     return pool_new(pool, conn_attr(v));
 }
@@ -1125,7 +1151,7 @@ VALUE libvirt_conn_create_pool_xml(VALUE
     xmlDesc = StringValueCStr(xml);
 
     pool = virStoragePoolCreateXML(conn, xmlDesc, NUM2UINT(flags));
-    _E(pool == NULL, conn, "virStoragePoolCreateXML");
+    _E(pool == NULL, create_error(e_OperationError, "virStoragePoolCreateXML", "", conn));
 
     return pool_new(pool, c);
 }
@@ -1138,7 +1164,7 @@ VALUE libvirt_conn_define_pool_xml(VALUE
     virConnectPtr conn = connect_get(c);
 
     pool = virStoragePoolDefineXML(conn, StringValueCStr(xml), NUM2UINT(flags));
-    _E(pool == NULL, conn, "virStoragePoolDefineXML");
+    _E(pool == NULL, create_error(e_DefinitionError, "virStoragePoolDefineXML", "", conn));
 
     return pool_new(pool, c);
 }
@@ -1198,7 +1224,7 @@ VALUE libvirt_pool_name(VALUE s) {
     const char *name;
 
     name = virStoragePoolGetName(pool_get(s));
-    _E(name == NULL, conn(s), "virStoragePoolGetName");
+    _E(name == NULL, create_error(e_RetrieveError, "virStoragePoolGetName", "", conn(s)));
 
     return rb_str_new2(name);
 }
@@ -1211,7 +1237,7 @@ VALUE libvirt_pool_uuid(VALUE s) {
     int r;
 
     r = virStoragePoolGetUUIDString(pool_get(s), uuid);
-    _E(r < 0, conn(s), "virStoragePoolGetUUIDString");
+    _E(r < 0, create_error(e_RetrieveError, "virStoragePoolGetUUIDString", "", conn(s)));
 
     return rb_str_new2((char *) uuid);
 }
@@ -1225,7 +1251,7 @@ VALUE libvirt_pool_info(VALUE s) {
     VALUE result;
 
     r = virStoragePoolGetInfo(pool_get(s), &info);
-    _E(r < 0, conn(s), "virStoragePoolGetInfo");
+    _E(r < 0, create_error(e_RetrieveError, "virStoragePoolGetInfo", "", conn(s)));
 
     result = rb_class_new_instance(0, NULL, c_storage_pool_info);
     rb_iv_set(result, "@state", INT2FIX(info.state));
@@ -1251,7 +1277,7 @@ VALUE libvirt_pool_autostart(VALUE s){
     int r, autostart;
 
     r = virStoragePoolGetAutostart(pool_get(s), &autostart);
-    _E(r < 0, conn(s), "virStoragePoolGetAutostart");
+    _E(r < 0, create_error(e_RetrieveError, "virStoragePoolGetAutostart", "", conn(s)));
 
     return autostart ? Qtrue : Qfalse;
 }
@@ -1269,7 +1295,7 @@ VALUE libvirt_pool_autostart_set(VALUE s
  */
 VALUE libvirt_pool_num_of_volumes(VALUE s) {
     int n = virStoragePoolNumOfVolumes(pool_get(s));
-    _E(n < 0, conn(s), "virStoragePoolNumOfVolumes");
+    _E(n < 0, create_error(e_RetrieveError, "virStoragePoolNumOfVolumes", "", conn(s)));
 
     return INT2FIX(n);
 }
@@ -1284,13 +1310,13 @@ VALUE libvirt_pool_list_volumes(VALUE s)
     VALUE result;
 
     num = virStoragePoolNumOfVolumes(pool);
-    _E(num < 0, conn(s), "virStoragePoolNumOfVolumes");
+    _E(num < 0, create_error(e_RetrieveError, "virStoragePoolNumOfVolumes", "", conn(s)));
 
     names = ALLOC_N(char *, num);
     r = virStoragePoolListVolumes(pool, names, num);
     if (r < 0) {
         free(names);
-        _E(r < 0, conn(s), "virStoragePoolListVolumes");
+        _E(r < 0, create_error(e_RetrieveError, "virStoragePoolListVolumes", "", conn(s)));
     }
 
     result = rb_ary_new2(num);
@@ -1315,7 +1341,7 @@ VALUE libvirt_pool_lookup_vol_by_name(VA
     virStorageVolPtr vol;
 
     vol = virStorageVolLookupByName(pool_get(p), StringValueCStr(name));
-    _E(vol == NULL, conn(p), "virStorageVolLookupByName");
+    _E(vol == NULL, create_error(e_RetrieveError, "virStorageVolLookupByName", "", conn(p)));
 
     return vol_new(vol, conn_attr(p));
 }
@@ -1328,7 +1354,7 @@ VALUE libvirt_pool_lookup_vol_by_key(VAL
 
     // FIXME: Why does this take a connection, not a pool ?
     vol = virStorageVolLookupByKey(conn(p), StringValueCStr(key));
-    _E(vol == NULL, conn(p), "virStorageVolLookupByKey");
+    _E(vol == NULL, create_error(e_RetrieveError, "virStorageVolLookupByKey", "", conn(p)));
 
     return vol_new(vol, conn_attr(p));
 }
@@ -1341,7 +1367,7 @@ VALUE libvirt_pool_lookup_vol_by_path(VA
 
     // FIXME: Why does this take a connection, not a pool ?
     vol = virStorageVolLookupByPath(conn(p), StringValueCStr(path));
-    _E(vol == NULL, conn(p), "virStorageVolLookupByPath");
+    _E(vol == NULL, create_error(e_RetrieveError, "virStorageVolLookupByPath", "", conn(p)));
 
     return vol_new(vol, conn_attr(p));
 }
@@ -1373,7 +1399,7 @@ VALUE libvirt_vol_create_xml(VALUE p, VA
     xmlDesc = StringValueCStr(xml);
 
     vol = virStorageVolCreateXML(pool_get(p), xmlDesc, NUM2UINT(flags));
-    _E(vol == NULL, c, "virNetworkCreateXML");
+    _E(vol == NULL, create_error(e_OperationError, "virNetworkCreateXML", "", c));
 
     return vol_new(vol, conn_attr(p));
 }
@@ -1395,7 +1421,7 @@ VALUE libvirt_vol_info(VALUE v) {
     VALUE result;
 
     r = virStorageVolGetInfo(vol_get(v), &info);
-    _E(r < 0, conn(v), "virStorageVolGetInfo");
+    _E(r < 0, create_error(e_RetrieveError, "virStorageVolGetInfo", "", conn(v)));
 
     result = rb_class_new_instance(0, NULL, c_storage_vol_info);
     rb_iv_set(result, "@type", INT2NUM(info.type));
@@ -1518,6 +1544,30 @@ void Init__libvirt() {
     m_libvirt = rb_define_module("Libvirt");
     c_libvirt_version = rb_define_class_under(m_libvirt, "Version",
                                               rb_cObject);
+
+
+    /*
+     * Libvirt Errors
+     */
+    e_Error =           rb_define_class_under(m_libvirt, "Error", 
+                                               rb_eStandardError);
+    e_ConnectionError = rb_define_class_under(m_libvirt, "ConnectionError", 
+                                                e_Error);
+    e_DefinitionError = rb_define_class_under(m_libvirt, "DefinitionError", 
+                                                e_Error);
+    e_RetrieveError =   rb_define_class_under(m_libvirt, "RetrieveError", 
+                                                e_Error);
+    e_OperationError =  rb_define_class_under(m_libvirt, "OperationError", 
+                                                e_Error);
+
+    // create 'libvirt_function_name' and 'vir_connect_ptr' attributes on e_Error class
+    rb_define_attr(e_Error, "libvirt_function_name", 1, 1);
+    rb_define_attr(e_Error, "vir_error", 1, 1);
+
+    /*
+     * Class Libvirt::VirError - core Libvirt error structure wrapper
+     */
+    c_vir_error = rb_define_class_under(m_libvirt, "VirError", rb_cObject);
 
     /*
      * Class Libvirt::Connect

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]