s4-samba-tool: improved exception handling in samba-tool
authorAndrew Tridgell <tridge@samba.org>
Mon, 29 Nov 2010 03:11:57 +0000 (14:11 +1100)
committerAndrew Tridgell <tridge@samba.org>
Mon, 29 Nov 2010 07:04:42 +0000 (18:04 +1100)
we now do reasonable printing on a wide range of common exception
classes, and always force a backtrace on an exception if the debug
level is >= 3

Pair-Programmed-With: Jelmer Vernooij <jelmer@samba.org>

source4/scripting/python/samba/netcmd/__init__.py

index 5a6a68cd29a4c34a82d05875dda3783b476f853a..aa74f657b2941a21a1b875a453bf6f7c594122cb 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import optparse
+import optparse, samba
 from samba import getopt as options
-import sys
+from ldb import LdbError
+import sys, traceback
 
 
 class Option(optparse.Option):
@@ -52,6 +53,40 @@ class Command(object):
             ret += " " + " ".join([x.upper() for x in self.takes_args])
         return ret
 
+    def show_command_error(self, e):
+        '''display a command error'''
+        if isinstance(e, CommandError):
+            (etype, evalue, etraceback) = e.exception_info
+            inner_exception = e.inner_exception
+            message = e.message
+            force_traceback = False
+        else:
+            (etype, evalue, etraceback) = sys.exc_info()
+            inner_exception = e
+            message = "uncaught exception"
+            force_traceback = True
+
+        if isinstance(inner_exception, LdbError):
+            (ldb_ecode, ldb_emsg) = inner_exception
+            print >>sys.stderr, "ERROR(ldb): %s - %s" % (message, ldb_emsg)
+        elif isinstance(inner_exception, AssertionError):
+            print >>sys.stderr, "ERROR(assert): %s" % message
+            force_traceback = True
+        elif isinstance(inner_exception, RuntimeError):
+            print >>sys.stderr, "ERROR(runtime): %s - %s" % (message, evalue)
+        elif type(inner_exception) is Exception:
+            print >>sys.stderr, "ERROR(exception): %s - %s" % (message, evalue)
+            force_traceback = True
+        elif inner_exception is None:
+            print >>sys.stderr, "ERROR: %s" % (message)
+        else:
+            print >>sys.stderr, "ERROR(%s): %s - %s" % (str(etype), message, evalue)
+            force_traceback = True
+
+        if force_traceback or samba.get_debug_level() >= 3:
+            traceback.print_tb(etraceback)
+
+
     synopsis = property(_get_synopsis)
 
     outf = sys.stdout
@@ -97,8 +132,8 @@ class Command(object):
             return -1
         try:
             return self.run(*args, **kwargs)
-        except CommandError, e:
-            print >>sys.stderr, "ERROR: %s" % e
+        except Exception, e:
+            self.show_command_error(e)
             return -1
 
     def run(self):
@@ -130,7 +165,11 @@ class SuperCommand(Command):
 
 
 class CommandError(Exception):
-    pass
+    '''an exception class for netcmd errors'''
+    def __init__(self, message, inner_exception=None):
+        self.message = message
+        self.inner_exception = inner_exception
+        self.exception_info = sys.exc_info()
 
 
 commands = {}