python: add error message to CsError and modify all tests to use CsError exception
diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py
index 7f7da69..5c341ac 100644
--- a/bindings/python/__init__.py
+++ b/bindings/python/__init__.py
@@ -1 +1 @@
-from capstone import Cs, cs_disasm_quick, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_MIPS, CS_ARCH_X86, CS_MODE_LITTLE_ENDIAN, CS_MODE_ARM, CS_MODE_THUMB, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL, CS_MODE_16, CS_MODE_32, CS_MODE_64, CS_OPT_SYNTAX_ATT, CS_MODE_BIG_ENDIAN
+from capstone import Cs, CsError, cs_disasm_quick, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_MIPS, CS_ARCH_X86, CS_MODE_LITTLE_ENDIAN, CS_MODE_ARM, CS_MODE_THUMB, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL, CS_MODE_16, CS_MODE_32, CS_MODE_64, CS_OPT_SYNTAX_ATT, CS_MODE_BIG_ENDIAN
diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py
index 48907a7..7b9ac5b 100644
--- a/bindings/python/capstone/__init__.py
+++ b/bindings/python/capstone/__init__.py
@@ -1 +1 @@
-from capstone import Cs, cs_disasm_quick, cs_version, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_MIPS, CS_ARCH_X86, CS_MODE_LITTLE_ENDIAN, CS_MODE_ARM, CS_MODE_THUMB, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL, CS_MODE_16, CS_MODE_32, CS_MODE_64, CS_OPT_SYNTAX_ATT, CS_MODE_BIG_ENDIAN, CS_MODE_MICRO, CS_MODE_N64
+from capstone import Cs, CsError, cs_disasm_quick, cs_version, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_MIPS, CS_ARCH_X86, CS_MODE_LITTLE_ENDIAN, CS_MODE_ARM, CS_MODE_THUMB, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL, CS_MODE_16, CS_MODE_32, CS_MODE_64, CS_OPT_SYNTAX_ATT, CS_MODE_BIG_ENDIAN, CS_MODE_MICRO, CS_MODE_N64
diff --git a/bindings/python/capstone/capstone.py b/bindings/python/capstone/capstone.py
index 51df469..30137be 100644
--- a/bindings/python/capstone/capstone.py
+++ b/bindings/python/capstone/capstone.py
@@ -172,6 +172,17 @@
     def __init__(self, errno):
         self.errno = errno
 
+    def __str__(self):
+        messages = { \
+            CS_ERR_MEM: "Out of memory (CsError)",
+            CS_ERR_ARCH: "Invalid architecture (CsError)",
+            CS_ERR_HANDLE: "Invalid handle (CsError)",
+            CS_ERR_CSH: "Invalid csh (CsError)",
+            CS_ERR_MODE: "Invalid mode (CsError)",
+            CS_ERR_OPTION: "Invalid option (CsError)",
+        }
+        return messages[self.errno]
+
 
 # quick & dirty Python function to disasm raw binary code
 def cs_disasm_quick(arch, mode, code, offset, count = 0):
@@ -268,6 +279,7 @@
         self.csh = ctypes.c_size_t()
         status = _cs.cs_open(arch, mode, ctypes.byref(self.csh))
         if status != CS_ERR_OK:
+            self.csh = None
             raise CsError(status)
 
         if arch == CS_ARCH_X86:
@@ -277,9 +289,10 @@
             self._syntax = None
 
     def __del__(self):
-        status = _cs.cs_close(self.csh)
-        if status != CS_ERR_OK:
-            raise CsError(status)
+        if self.csh:
+            status = _cs.cs_close(self.csh)
+            if status != CS_ERR_OK:
+                raise CsError(status)
 
     #def option(self, opt_type, opt_value):
     #    return _cs.cs_option(self.csh, opt_type, opt_value)
diff --git a/bindings/python/test.py b/bindings/python/test.py
index d646b6c..075931d 100755
--- a/bindings/python/test.py
+++ b/bindings/python/test.py
@@ -68,8 +68,8 @@
 
             print("0x%x:" % (insn.address + insn.size))
             print
-        except:
-            print("ERROR: Arch or mode unsupported!")
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 #test_cs_disasm_quick()
diff --git a/bindings/python/test_arm.py b/bindings/python/test_arm.py
index 40d1a96..db14158 100755
--- a/bindings/python/test_arm.py
+++ b/bindings/python/test_arm.py
@@ -93,8 +93,8 @@
                 print_insn_detail(insn)
                 print
             print "0x%x:\n" % (insn.address + insn.size)
-        except:
-            print("ERROR: Arch or mode unsupported!")
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 test_class()
diff --git a/bindings/python/test_arm64.py b/bindings/python/test_arm64.py
index 76efa20..2342f28 100755
--- a/bindings/python/test_arm64.py
+++ b/bindings/python/test_arm64.py
@@ -78,8 +78,8 @@
                 print_insn_detail(insn)
                 print
             print "0x%x:\n" % (insn.address + insn.size)
-        except:
-            print("ERROR: Arch or mode unsupported!")
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 test_class()
diff --git a/bindings/python/test_detail.py b/bindings/python/test_detail.py
index 8fb0d88..66567f0 100755
--- a/bindings/python/test_detail.py
+++ b/bindings/python/test_detail.py
@@ -63,7 +63,6 @@
             if syntax != 0:
                 md.syntax = syntax
 
-
             for insn in md.disasm(code, 0x1000):
                 print("0x%x:\t%s\t%s  // insn-ID: %u, insn-mnem: %s" \
                     %(insn.address, insn.mnemonic, insn.op_str, insn.id, \
@@ -71,8 +70,8 @@
                 print_detail(insn)
 
             print
-        except:
-            print("ERROR: Arch or mode unsupported!")
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 test_class()
diff --git a/bindings/python/test_mips.py b/bindings/python/test_mips.py
index 1fba592..5603f34 100755
--- a/bindings/python/test_mips.py
+++ b/bindings/python/test_mips.py
@@ -61,8 +61,8 @@
                 print
 
             print "0x%x:\n" %(insn.address + insn.size)
-        except:
-            print("ERROR: Arch or mode unsupported!")
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 test_class()
diff --git a/bindings/python/test_x86.py b/bindings/python/test_x86.py
index 66dad2b..7100acf 100755
--- a/bindings/python/test_x86.py
+++ b/bindings/python/test_x86.py
@@ -108,15 +108,18 @@
         print("Code: %s" % to_hex(code))
         print("Disasm:")
 
-        md = Cs(arch, mode)
+        try:
+            md = Cs(arch, mode)
 
-        if syntax != 0:
-            md.syntax = syntax
+            if syntax != 0:
+                md.syntax = syntax
 
-        for insn in md.disasm(code, 0x1000):
-            print_insn_detail(mode, insn)
-            print
-        print ("0x%x:\n" % (insn.address + insn.size))
+            for insn in md.disasm(code, 0x1000):
+                print_insn_detail(mode, insn)
+                print
+            print ("0x%x:\n" % (insn.address + insn.size))
+        except CsError as e:
+            print("ERROR: %s" %e)
 
 
 test_class()