[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



Mohammed Morsi wrote:
Attached is the new patch incorporating everyone's feedback, specifically:
*  c_vir_error gone, just was a relic from the last patch
* exception attributes are now read only
* vir_error attribute changed to libvirt_message.
* removed e_OperationError, replaced instances with base e_Error
* Cleaned up some of the specific errors
* Other specific error info has not been added yet. The current implementation has the basis for adding data to each error. If more granularity is desired, I say we commit what is there now and we can add more info if needed. (specifically relating to the "connection" error which is now thrown by the "open" method, more information can be added to discriminate against, but I need to know specifically what is needed and how it is set (eg. a boolean which I should set upon inspecting the return value of virConnectOpen, the actual return value, etc)).





------------------------------------------------------------------------

_______________________________________________
Ovirt-devel mailing list
Ovirt-devel redhat com
https://www.redhat.com/mailman/listinfo/ovirt-devel
Improved patch where I fixed few compilation errors (not sure how they crept in there)


diff -r 6ea23e0ba97d ext/libvirt/_libvirt.c
--- a/ext/libvirt/_libvirt.c	Tue Apr 01 11:27:43 2008 -0700
+++ b/ext/libvirt/_libvirt.c	Wed Apr 02 13:42:46 2008 -0400
@@ -17,11 +17,12 @@
  * 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;
@@ -41,6 +42,13 @@ 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
 
 /*
  * Internal helpers
@@ -73,6 +81,32 @@ static VALUE generic_new(VALUE klass, vo
     return result;
 }
 
+/* Error handling */
+#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);
+}
+
+static VALUE create_error(VALUE error, char* method, char* msg, 
+                                virConnectPtr conn){
+    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, "@libvirt_message", rb_str_new2(err.message));
+
+    return ruby_errinfo;
+};
+
+
 /* Connections */
 static void connect_close(void *p) {
     int r;
@@ -80,8 +114,7 @@ static void connect_close(void *p) {
     if (!p)
         return;
     r = virConnectClose((virConnectPtr) p);
-    if (r < 0)
-        rb_raise(rb_eSystemCallError, "Connection close failed");
+    _E(r < 0, create_error(rb_eSystemCallError, "connect_close", "Connection close failed", p));
 }
 
 static VALUE connect_new(virConnectPtr p) {
@@ -169,16 +202,6 @@ 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);
-}
-
 /*
  * Code generating macros.
  *
@@ -197,7 +220,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 +239,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 +265,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 +279,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)                                                    \
@@ -273,7 +296,7 @@ static void vir_error(virConnectPtr conn
         Data_Get_Struct(s, vir##kind, ptr);                             \
         if (ptr != NULL) {                                              \
             int r = vir##kind##Free(ptr);                               \
-            _E(r < 0, conn(s), "vir" #kind "Free");                     \
+            _E(r < 0, create_error(e_Error, "vir" #kind "Free", "", conn(s) ));    \
             DATA_PTR(s) = NULL;                                         \
         }                                                               \
         return Qnil;                                                    \
@@ -302,8 +325,7 @@ VALUE libvirt_version(VALUE m, VALUE t) 
 
     type = StringValueCStr(t);
     r = virGetVersion(&libVer, type, &typeVer);
-    if (r < 0)
-        rb_raise(rb_eArgError, "Failed to get version for %s", type);
+    _E(r < 0, create_error(e_Error, "libvirt_version", "Failed to get version", NULL));
 
     result = rb_ary_new2(2);
     argv[0] = rb_str_new2("libvirt");
@@ -326,12 +348,10 @@ VALUE libvirt_open(VALUE m, VALUE url) {
 
     if (url) {
         str = StringValueCStr(url);
-        if (!str)
-            rb_raise(rb_eTypeError, "expected string");
+        if(!str) rb_raise(rb_eTypeError, "expected string");
     }
     virConnectPtr ptr = virConnectOpen(str);
-    if (!ptr)
-        rb_raise(rb_eArgError, "Failed to open %s", str);
+    _E(!ptr, create_error(e_ConnectionError, "virConnectOpen", "Failed to open", NULL));
     return connect_new(ptr);
 }
 
@@ -347,11 +367,11 @@ VALUE libvirt_open_read_only(VALUE m, VA
 
     if (url) {
         str = StringValueCStr(url);
-        if (!str)
-            rb_raise(rb_eTypeError, "expected string");
+        if (!str) 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);
 }
@@ -411,7 +431,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);
 }
@@ -444,7 +464,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);
 }
@@ -460,7 +480,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);
 
@@ -501,13 +521,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);
@@ -675,7 +695,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));
@@ -703,7 +723,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);
 }
@@ -717,7 +737,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);
 }
@@ -738,7 +758,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);
 }
@@ -751,7 +771,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);
 }
@@ -764,7 +784,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);
 }
@@ -777,7 +797,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);
 }
@@ -791,7 +811,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;
 }
@@ -807,7 +827,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);
@@ -821,7 +841,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;
 }
@@ -859,7 +879,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;
 }
@@ -883,7 +903,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_Error, "virDomainCreateLinux", "", conn));
 
     return domain_new(dom, c);
 }
@@ -896,7 +916,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);
 }
@@ -909,7 +929,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);
 }
@@ -922,7 +942,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);
 }
@@ -935,7 +955,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);
 }
@@ -960,7 +980,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);
 }
@@ -973,7 +993,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);
 }
@@ -989,7 +1009,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_Error, "virNetworkCreateXML", "", conn));
 
     return network_new(netw, c);
 }
@@ -1002,7 +1022,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);
 }
@@ -1050,7 +1070,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);
 }
@@ -1079,7 +1099,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;
 }
@@ -1113,7 +1133,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);
 }
@@ -1126,7 +1146,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);
 }
@@ -1138,7 +1158,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));
 }
@@ -1154,7 +1174,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_Error, "virStoragePoolCreateXML", "", conn));
 
     return pool_new(pool, c);
 }
@@ -1167,7 +1187,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);
 }
@@ -1227,7 +1247,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);
 }
@@ -1240,7 +1260,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);
 }
@@ -1254,7 +1274,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));
@@ -1280,7 +1300,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;
 }
@@ -1298,7 +1318,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);
 }
@@ -1313,13 +1333,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);
@@ -1351,7 +1371,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));
 }
@@ -1364,7 +1384,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));
 }
@@ -1377,7 +1397,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));
 }
@@ -1409,7 +1429,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_Error, "virNetworkCreateXML", "", c));
 
     return vol_new(vol, conn_attr(p));
 }
@@ -1431,7 +1451,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));
@@ -1563,6 +1583,23 @@ 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);
+
+    // create 'libvirt_function_name' and 'vir_connect_ptr' attributes on e_Error class
+    rb_define_attr(e_Error, "libvirt_function_name", 1, 0);
+    rb_define_attr(e_Error, "libvirt_message", 1, 0);
 
     /*
      * Class Libvirt::Connect

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