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

[minion-cvs] Improve error handling and server startup reporting:



Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv10608/lib/mixminion

Modified Files:
	ClientMain.py Common.py 
Log Message:
Improve error handling and server startup reporting:

ClientMain:
        - Change many messages to UIError exceptions

ModuleManager:
        - Downgrade 'Disabling module' from info to debug.

Common, ServerMain:
        - Change daemonization and log configuration to avoid shutting down
          console messages until the first moment we enter the main loop.
          This should make it easier to notice when the server hits an
          exception on startup.



Index: ClientMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientMain.py,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- ClientMain.py	13 Feb 2003 06:30:22 -0000	1.53
+++ ClientMain.py	13 Feb 2003 07:03:49 -0000	1.54
@@ -293,16 +293,16 @@
 
         # Have we already imported this server?
         if self.digestMap.get(info.getDigest(), "X").startswith("I:"):
-            raise MixError("Server descriptor is already imported")
+            raise UIError("Server descriptor is already imported")
 
         # Is the server expired?
         if info.isExpiredAt(time.time()):
-            raise MixError("Server desciptor is expired")
+            raise UIError("Server desciptor is expired")
 
         # Is the server superseded?
         if self.byNickname.has_key(lcnickname):
             if info.isSupersededBy([s for s,_ in self.byNickname[lcnickname]]):
-                raise MixError("Server descriptor is superseded")
+                raise UIError("Server descriptor is already superseded")
 
         # Copy the server into DIR/servers.
         fnshort = "%s-%s"%(nickname, formatFnameTime())
@@ -496,13 +496,13 @@
             try:
                 return ServerInfo(fname=fname, assumeValid=0)
             except OSError, e:
-                raise MixError("Couldn't read descriptor %r: %s" %
+                raise UIError("Couldn't read descriptor %r: %s" %
                                (name, e))
             except ConfigError, e:
-                raise MixError("Couldn't parse descriptor %r: %s" %
+                raise UIError("Couldn't parse descriptor %r: %s" %
                                (name, e))
         elif strict:
-            raise MixError("Couldn't find descriptor %r" % name)
+            raise UIError("Couldn't find descriptor for %r" % name)
         else:
             return None
 
@@ -549,7 +549,7 @@
             # If so, find all candidates...
             endList = self.__find(self.byCapability[endCap],startAt,endAt)
             if not endList:
-                raise MixError("No %s servers known" % endCap)
+                raise UIError("Can't build path: no %s servers known" % endCap)
             # ... and pick one that hasn't been used, if possible.
             used = [ info.getNickname().lower() for info in startServers ]
             unusedEndList = [ info for info in endList
@@ -622,7 +622,7 @@
             midServers = midList
         else:
             # We don't know any servers at all.
-            raise MixError("No relays known")
+            raise UIError("No relays known")
 
         LOG.debug("getPath: [%s][%s][%s]",
                   " ".join([ s.getNickname() for s in startServers ]),
@@ -686,13 +686,13 @@
     # Make sure all relay servers support relaying.
     for server in path[:-1]:
         if "relay" not in server.getCaps():
-            raise MixError("Server %s does not support relay"
-                           % server.getNickname())
+            raise UIError("Server %s does not support relay"
+                          % server.getNickname())
 
     # Make sure the exit server can support the exit capability.
     if exitCap and exitCap not in path[-1].getCaps():
-        raise MixError("Server %s does not support %s"
-                       % (path[-1].getNickname(), exitCap))
+        raise UIError("Server %s does not support %s capability"
+                      % (path[-1].getNickname(), exitCap))
 
     # If there is no specified swap point, find one.
     if nSwap is None:
@@ -700,7 +700,7 @@
 
     path1, path2 = path[:nSwap+1], path[nSwap+1:]
     if not halfPath and (not path1 or not path2):
-        raise MixError("Each leg of the path must have at least 1 hop")
+        raise UIError("Each leg of the path must have at least 1 hop")
     return path1, path2
 
 def parsePath(directory, config, path, address, nHops=None,
@@ -765,12 +765,12 @@
         ent = path[idx]
         if ent == "*":
             if starPos is not None:
-                raise MixError("Can't have two wildcards in a path")
+                raise UIError("Can't have two wildcards in a path")
             starPos = idx
             cur = exitPath
         elif ent == "*swap*":
             if swapPos is not None:
-                raise MixError("Can't specify swap point twice")
+                raise UIError("Can't specify swap point twice")
             swapPos = idx
         else:
             cur.append(ent)
@@ -810,15 +810,15 @@
     # Check myNSwap for consistency
     if nSwap is not None:
         if myNSwap is not None and myNSwap != nSwap:
-            raise MixError("Mismatch between specified swap points")
+            raise UIError("Mismatch between specified swap points")
         myNSwap = nSwap
 
     # Check myNHops for consistency
     if nHops is not None:
         if myNHops is not None and myNHops != nHops:
-            raise MixError("Mismatch between specified number of hops")
+            raise UIrror("Mismatch between specified number of hops")
         elif nHops < len(enterPath)+len(exitPath):
-            raise MixError("Mismatch between specified number of hops")
+            raise UIError("Mismatch between specified number of hops")
 
         myNHops = nHops
 
@@ -1561,7 +1561,7 @@
         sys.exit(1)
     except ConfigError, e:
         print >>sys.stderr, "Error in configuration file %r"%configFile
-        print >>sys.stderr, str(e)
+        print >>sys.stderr, "   ", str(e)
         sys.exit(1)
     return None #suppress pychecker warning
 
@@ -1988,8 +1988,7 @@
         LOG.info("Sending dummy message")
     else:
         if address and address.getRouting()[0] == DROP_TYPE:
-            LOG.error("Cannot send a payload with a DROP message.")
-            sys.exit(0)
+            raise UIError("Cannot send a payload with a DROP message.")
 
         if inFile is None:
             inFile = "-"
@@ -2048,7 +2047,7 @@
             try:
                 directory.importFromFile(filename)
             except MixError, e:
-                print "Error while importing: %s" % e
+                print "Error while importing %s: %s" % (filename, e)
     finally:
         clientUnlock()
         
@@ -2166,14 +2165,13 @@
         sys.exit(1)
 
     if args:
-        print >>sys.stderr, "Error: unexpected arguments."
+        msg = "Unexpected arguments."
         if len(args) == 1:
-            print >>sys.stderr, "       (Did you mean '-i %s'?)" %args[0]
-        sys.exit(1)
+            msg += " (Did you mean '-i %s'?)" % args[0]
+        raise UIError(msg)
 
     if not inputFile:
-        print >> sys.stderr, "Error: No input file specified"
-        sys.exit(1)
+        raise UIError("No input file specified")
 
     parser.init()
     client = parser.client
@@ -2196,9 +2194,7 @@
     try:
         res = client.decodeMessage(s, force=force)
     except ParseError, e:
-        print "Couldn't parse message: %s"%e
-        out.close()
-        sys.exit(1)
+        raise UIError("Couldn't parse message: %s"%e)
         
     for r in res:
         out.write(r)
@@ -2279,7 +2275,8 @@
         sys.exit(0)
 
     if args:
-        print >>sys.stderr, "Unexpected arguments"
+        print >>sys.stderr, "ERROR: Unexpected arguments"
+        print _GENERATE_SURB_USAGE % cmd
         sys.exit(1)
 
     parser.init()

Index: Common.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Common.py,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- Common.py	13 Feb 2003 06:30:22 -0000	1.60
+++ Common.py	13 Feb 2003 07:03:49 -0000	1.61
@@ -51,10 +51,10 @@
     """Exception raised for an error that should be reported to the user,
        not dumped as a stack trace."""
     def dump(self):
-        if str(self): print "ERROR:", str(self)
+        if str(self): print >>sys.stderr, "ERROR:", str(self)
     def dumpAndExit(self):
         self.dump()
-        sys.exit(0)
+        sys.exit(1)
 
 class UsageError(UIError):
     """Exception raised for an error that should be reported to the user
@@ -398,10 +398,13 @@
         self.setMinSeverity(minSeverity)
         self.__lock = threading.Lock()
 
-    def configure(self, config):
+    def configure(self, config, keepStderr=0):
         """Set up this Log object based on a ServerConfig or ClientConfig
-           object"""
+           object
 
+           If keepStderr is true, do not silence the console log, regardless
+           of the value of 'Daemon' or 'EchoMessages'.
+           """
         self.handlers = []
         if config == None or not config.has_section("Server"):
             self.setMinSeverity("WARN")
@@ -409,6 +412,7 @@
         else:
             self.setMinSeverity(config['Server'].get('LogLevel', "WARN"))
             logfile = config['Server'].get('LogFile',None)
+            # ???? Does this even work if 'logfile' is not given?
             if logfile is None:
                 homedir = config['Server']['Homedir']
                 if homedir:
@@ -419,6 +423,8 @@
                     self.addHandler(_FileLogHandler(logfile))
                 except MixError, e:
                     self.error(str(e))
+                if keepStderr:
+                    return
                 if (config['Server'].get('Daemon',0) or
                     not config['Server'].get('EchoMessages',0)):
                     print "Silencing the console log; look in %s instead"%(