At Mon, 23 Jul 2012 14:56:55 -0600,
Eric Blake wrote:
On 07/23/2012 04:31 AM, Claudio Bley wrote:
>> When libvirt returns an error code which is not mapped in enum
>> ErrorNumber, an IndexOutOfBoundsException is thrown.
>>
>> I realize that the freshly released libvirt-java 0.4.8 supports all
>> error codes up to libvirt 0.9.12. But that doesn't fix the problem.
>>
>> Would it be feasible to add a special UNKNOWN enum value?
I think that might be better, after all. With your patch...
> public Error(virError vError) {
> - code = ErrorNumber.values()[vError.code];
> - domain = ErrorDomain.values()[vError.domain];
> - level = ErrorLevel.values()[vError.level];
> + if (ErrorNumber.values().length > vError.code)
> + code = ErrorNumber.values()[vError.code];
the old version crashed, and your version leaves code as null (which is
a strict improvement, but might cause its own NullPointer issue later
on). Having an else branch that sticks in a placeholder would be nicer
to end clients to at least recognize that they are talking to a newer
server, without crashing.
Please have look at the following patch.
-- >8 --
Subject: [PATCH] Fix IndexOutOfBoundsException for unknown error
number/domain/level codes.
Remove default constructor because it does not init the object properly.
Add a special *_UNKNOWN enum value to each enum which is used when the
given enum code is out of bounds.
---
src/main/java/org/libvirt/Error.java | 42 +++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/src/main/java/org/libvirt/Error.java b/src/main/java/org/libvirt/Error.java
index f185ce0..a345b82 100644
--- a/src/main/java/org/libvirt/Error.java
+++ b/src/main/java/org/libvirt/Error.java
@@ -12,6 +12,20 @@ import org.libvirt.jna.virError;
*/
public class Error implements Serializable {
+ /**
+ * Map an integer to an enum value.
+ *
+ * @return when {@code n < values.length} return n-th item of
+ * {@code values}, otherwise the last item of array
+ * {@code values}.
+ */
+ private static final <T extends Enum<T>> T wrapToEnum(final int n, final
T[] values) {
+ assert(n >= 0 && values.length > 0);
+
+ int idx = Math.min(n, values.length - 1);
+ return values[idx];
+ }
+
public static enum ErrorDomain {
VIR_FROM_NONE, VIR_FROM_XEN, /* Error at Xen hypervisor layer */
VIR_FROM_XEND, /* Error at connection with xend daemon */
@@ -60,6 +74,11 @@ public class Error implements Serializable {
VIR_FROM_URI, /* Error from URI handling */
VIR_FROM_AUTH, /* Error from auth handling */
VIR_FROM_DBUS, /* Error from DBus */
+ VIR_FROM_UNKNOWN; /* unknown error domain (must be the last entry!) */
+
+ protected static final ErrorDomain wrap(int value) {
+ return wrapToEnum(value, values());
+ }
}
public static enum ErrorLevel {
@@ -71,7 +90,13 @@ public class Error implements Serializable {
/**
* An error
*/
- VIR_ERR_ERROR
+ VIR_ERR_ERROR,
+
+ VIR_ERR_UNKNOWN; /* must be the last entry! */
+
+ protected static final ErrorLevel wrap(int value) {
+ return wrapToEnum(value, values());
+ }
}
public static enum ErrorNumber {
@@ -161,6 +186,11 @@ public class Error implements Serializable {
VIR_ERR_MIGRATE_UNSAFE, /* Migration is not safe */
VIR_ERR_OVERFLOW, /* integer overflow */
VIR_ERR_BLOCK_COPY_ACTIVE, /* action prevented by block copy job */
+ VIR_ERR_UNKNOWN; /* unknown error (must be the last entry!) */
+
+ protected static final ErrorNumber wrap(int value) {
+ return wrapToEnum(value, values());
+ }
}
/**
@@ -181,14 +211,10 @@ public class Error implements Serializable {
int int2;
NetworkPointer VNP; /* Deprecated */
- public Error() {
-
- }
-
public Error(virError vError) {
- code = ErrorNumber.values()[vError.code];
- domain = ErrorDomain.values()[vError.domain];
- level = ErrorLevel.values()[vError.level];
+ code = code.wrap(vError.code);
+ domain = domain.wrap(vError.domain);
+ level = level.wrap(vError.level);
message = vError.message;
str1 = vError.str1;
str2 = vError.str2;
--
1.7.11.msysgit.0
--
AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany
Phone: +49 341 265 310 19
Web:<http://www.av-test.org>
Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076)
Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern