[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r6240 - in trunk/gnue-common/src: apps datasources
From: |
johannes |
Subject: |
r6240 - in trunk/gnue-common/src: apps datasources |
Date: |
Thu, 2 Sep 2004 06:47:26 -0500 (CDT) |
Author: johannes
Date: 2004-09-02 06:47:24 -0500 (Thu, 02 Sep 2004)
New Revision: 6240
Modified:
trunk/gnue-common/src/apps/GBaseApp.py
trunk/gnue-common/src/apps/errors.py
trunk/gnue-common/src/datasources/GConnections.py
Log:
Added an exception hook for uncaught exceptions
Modified: trunk/gnue-common/src/apps/GBaseApp.py
===================================================================
--- trunk/gnue-common/src/apps/GBaseApp.py 2004-09-02 09:46:27 UTC (rev
6239)
+++ trunk/gnue-common/src/apps/GBaseApp.py 2004-09-02 11:47:24 UTC (rev
6240)
@@ -34,11 +34,14 @@
from gnue import paths
-from gnue.common.apps import GConfig
+from gnue.common.apps import GConfig, errors
from gnue.common.apps import GDebug
from gnue.common.datasources import GConnections
from CommandOption import CommandOption
+class StartupError (errors.UserError):
+ pass
+
class GBaseApp:
"""
The base class of the various GNUe application classes.
@@ -81,109 +84,113 @@
def __init__(self, connections=None, application='common', defaults=None):
+ sys.excepthook = self.excepthook
+
# Basic options
self._base_options = [
+ ##
+ ## Base options
+ ##
+ CommandOption ('version', category = "base", action = self.doVersion,
+ help = _('Displays the version information for this program.')),
- ##
- ## Base options
- ##
+ CommandOption ('debug-level', category = "base", default = 0,
+ argument = _("level"),
+ help = _('Enables debugging messages. Argument specifies the '
+ 'level of messages to display (e.g., "--debug-level 5" '
+ 'displays all debugging messages at level 5 or below.)')),
- CommandOption('version', category="base", action=self.doVersion,
- help=_('Displays the version information for this program.') ),
+ CommandOption ('debug-file', category = "base", argument = _("filename"),
+ help = _('Sends all debugging messages to a specified file '
+ '(e.g., "--debug-file trace.log" sends all output to '
+ '"trace.log")')),
- CommandOption('debug-level', category="base", default=0,
argument=_("level"),
- help=_('Enables debugging messages. Argument specifies the '
- 'level of messages to display (e.g., "--debug-level 5"
displays '
- 'all debugging messages at level 5 or below.)') ),
+ CommandOption ('help', category = "base", action = self.printHelp,
+ help = _('Displays this help screen.')),
- CommandOption('debug-file', category="base", argument=_("filename"),
- help=_('Sends all debugging messages to a specified file '
- '(e.g., "--debug-file trace.log" sends all output to
"trace.log")') ),
+ CommandOption ('help-config', category = "base",
+ action = self.doHelpConfig,
+ help = _('Displays a list of valid configuration file entries, their '
+ 'purpose, and their default values.')),
- CommandOption('help', category="base", action=self.printHelp,
- help=_('Displays this help screen.') ),
+ ##
+ ## Developer options
+ ##
- CommandOption('help-config', category="base",
action=self.doHelpConfig,
- help=_('Displays a list of valid configuration file entries,
their '
- 'purpose, and their default values.') ),
+ CommandOption ('help-dev', category = "base", action = self.printHelpDev,
+ help = _('Display all options of interest to core developers. ')),
- ##
- ## Developer options
- ##
+ CommandOption ('selfdoc', category = "dev", action = self.doSelfDoc,
+ argument = _("type[,subtype]"),
+ help = _('Generates self-documentation.')),
- CommandOption('help-dev', category="base", action=self.printHelpDev,
- help=_('Display all options of interest to core developers. ') ),
+ CommandOption ('selfdoc-format', category = "dev", argument =
_("format"),
+ help = _('Format to output the self-documentation in. Supported '
+ 'formats are dependent on the type of selfdoc being '
+ 'created.')),
- CommandOption('selfdoc', category="dev", action=self.doSelfDoc,
- argument=_("type[,subtype]"),
- help=_('Generates self-documentation.') ),
+ CommandOption ('selfdoc-file', category = "dev", argument =
_("filename"),
+ help = _('Specifies the filename that selfdoc should write to. If not '
+ 'provided, output is sent to stdout.')),
- CommandOption('selfdoc-format', category="dev", argument=_("format"),
- help=_('Format to output the self-documentation in. Supported
formats '
- 'are dependent on the type of selfdoc being created.') ),
+ CommandOption ('selfdoc-options', category = "dev",
+ argument = _("options"),
+ help = _('Options specific to individual selfdoc types.')),
- CommandOption('selfdoc-file', category="dev", argument=_("filename"),
- help=_('Specifies the filename that selfdoc should write to. If
not provided, output is sent to stdout.') ),
+ CommandOption ('profile', category = "dev",
+ help = _("Run Python's built-in profiler and display the resulting "
+ "run statistics.")),
- CommandOption('selfdoc-options', category="dev",
argument=_("options"),
- help=_('Options specific to individual selfdoc types.') ),
-
- CommandOption('profile', category="dev",
- help=_("Run Python's built-in profiler and display the resulting
"
- "run statistics.") ),
-
- CommandOption('interactive-debugger', category="dev",
- help=_("Run the app inside Python's built-in debugger ")),
+ CommandOption ('interactive-debugger', category = "dev",
+ help = _("Run the app inside Python's built-in debugger ")),
]
if self.USE_DATABASE_OPTIONS:
self.USE_CONNECTIONS = 1
- self._base_options += [
+ self._base_options.extend ([ \
+ CommandOption ('username', category = "connections", default = '',
+ argument = 'name',
+ help = _('Username used to log into the database. Note that if '
+ 'specified, this will be used for all databases. If not '
+ 'supplied, the program will prompt for username.')),
- CommandOption('username', category="connections", default='',
- argument='name',
- help=_('Username used to log into the database. Note that if '
- 'specified, this will be used for all databases. If not '
- 'supplied, the program will prompt for username.') ),
+ CommandOption ('password', category = "connections", default = '',
+ argument = 'passwd',
+ help = _('Password used to log into the database. Note that if '
+ 'specified, this will be used for all databases. If not '
+ 'supplied, the program will prompt for password if needed.'
+ '\nNOTE: SUPPLYING A PASSWORD VIA THE COMMAND LINE MAY BE '
+ 'CONSIDERED A SECURITY RISK AND IS NOT RECOMMENDED.'))])
- CommandOption('password', category="connections", default='',
- argument='passwd',
- help=_('Password used to log into the database. Note that if '
- 'specified, this will be used for all databases. If not '
- 'supplied, the program will prompt for password if
needed.'
- '\nNOTE: SUPPLYING A PASSWORD VIA THE COMMAND LINE MAY BE
'
- 'CONSIDERED A SECURITY RISK AND IS NOT RECOMMENDED.)') )
- ]
-
if self.USE_CONNECTIONS:
self._base_options += [
- CommandOption('help-connections', category="base",
action=self.printHelpConn,
- help=_('Display help information related to database '
- 'connections, including a list of available drivers.') ),
+ CommandOption ('help-connections', category = "base",
+ action = self.printHelpConn,
+ help = _('Display help information related to database '
+ 'connections, including a list of available drivers.')),
- CommandOption('connections', category="connections",
- argument="loc",
- help=_('Specifies the location of the connection definition
file. '
- '<loc> may specify a file name '
- '(/usr/local/gnue/etc/connections.conf),'
- 'or a URL location '
- '(http://localhost/connections.conf).'
- 'If this option is not specified, the environent variable
'
- 'GNUE_CONNECTIONS is checked.'
- 'If neither of them is set, "%s" is used as a default.') %
+ CommandOption ('connections', category = "connections",
+ argument = "loc",
+ help = _('Specifies the location of the connection definition file. '
+ '<loc> may specify a file name '
+ '(/usr/local/gnue/etc/connections.conf),'
+ 'or a URL location '
+ '(http://localhost/connections.conf).'
+ 'If this option is not specified, the environent variable '
+ 'GNUE_CONNECTIONS is checked.'
+ 'If neither of them is set, "%s" is used as a default.') %
os.path.join (paths.config, "connections.conf")) ]
# Python version check
- try:
- if sys.hexversion < 0x02010000:
- self.handleStartupError (u_("This application requires Python 2.1 or "
- "greater. You are running Python %s") % sys.version [:5])
- except AttributeError:
- # Really, really old version of Python...
- self.handleStartupError (_("This application requires Python 2.1 or "
- "greater."))
+ if not hasattr (sys, 'hexversion') or sys.hexversion < 0x02010000:
+ msg = _("This application requires Python 2.1 or greater.")
+ if hasattr (sys, 'version'):
+ msg = u_("This application requires Python 2.1 or greater. "
+ "You are running Python %s") % sys.version [:5]
+ raise errors.AdminError, msg
+
#
# Get all command line options and arguments
#
@@ -224,9 +231,10 @@
sys.argv=[]
try:
- opt, self.ARGUMENTS = getopt.getopt(sys.argv[1:], shortoptions,
longoptions)
+ opt, self.ARGUMENTS = getopt.getopt (sys.argv[1:], shortoptions,
+ longoptions)
except getopt.error, msg:
- self.handleStartupError(msg)
+ raise StartupError, "%s" % msg
pendingActions = []
for o in opt:
@@ -259,28 +267,21 @@
GDebug.setDebug(int("%s" % self.OPTIONS['debug-level']),
self.OPTIONS['debug-file'])
except ValueError:
- self.handleStartupError(_('The debug_level option ("-d") expects a
numerical value.'))
+ raise StartupError, \
+ _('The debug_level option ("-d") expects a numerical value.')
+ gDebug (1, "Python %s" % sys.version)
+ gDebug (1, "Run Options: %s" % opt)
+ gDebug (1, "Run Arguments: %s" % self.ARGUMENTS)
-
- GDebug.printMesg(1,"Python %s" % sys.version)
- GDebug.printMesg(1,"Run Options: %s" % opt)
- GDebug.printMesg(1,"Run Arguments: %s" % self.ARGUMENTS)
-
# Read the config files
if application:
try:
- self.configurationManager = GConfig.GConfig(application, defaults,
configFilename=self.CONFIGFILE)
+ self.configurationManager = GConfig.GConfig (application, defaults,
+ configFilename = self.CONFIGFILE)
except ConfigParser.NoSectionError, msg:
- self.handleStartupError (u_("The gnue.conf file is incomplete:\n"
- " %s") % msg)
- except Exception, msg:
- etype = string.splitfields (str (sys.exc_type), '.')
- etype.reverse ()
- self.handleStartupError (u_("%(exType)s while reading gnue.conf:\n"
- " %(message)s") \
- % {'exType' : etype [0],
- 'message': msg})
+ raise errors.AdminError, \
+ u_("The gnue.conf file is incomplete:\n %s") % msg
# Add custom import to python's namespace
try:
@@ -313,10 +314,6 @@
self.connections_file = os.environ['GNUE_CONNECTIONS']
else:
self.connections_file = os.path.join (paths.config, "connections.conf")
-# self.handleStartupError(
-# _('Unable to load the connections definition file.\n') \
-# + _('\n Please set the environmental variable GNUE_CONNECTIONS
or ') \
-# + _('\n use the "-f" command option.'))
GDebug.printMesg(1, 'Connection Definition: "%s"' %
self.connections_file)
@@ -324,16 +321,14 @@
self.connections = GConnections.GConnections (self.connections_file,
loginOptions = lhOptions)
except GConnections.InvalidFormatError, msg:
- self.handleStartupError(
+ raise errors.AdminError, \
u_("Unable to load the connections definition file.\n\n"
- "The connections file is in an invalid format.\n%s") % msg)
+ "The connections file is in an invalid format.\n%s") % msg
- except IOError:
- self.handleStartupError (
- u_("Unable to load the connections definition file.\n\n"
- "The connections file specified either does "
- "not exist or is not readable by your account.\n"
- "Location: \"%s\"") % self.connections_file)
+ except IOError, err:
+ raise StartupError, \
+ u_("Unable to load the connections definition file: %s.") \
+ % self.connections_file
def addCommandOption(self, *args, **parms):
self.COMMAND_OPTIONS.append(CommandOption(*args, **parms))
@@ -565,3 +560,26 @@
self.printHelpHeader()
print GConfig.printableConfigOptions(defaults)
sys.exit()
+
+
+ # ---------------------------------------------------------------------------
+ # Catch an exception
+ # ---------------------------------------------------------------------------
+
+ def excepthook (self, etype, value, traceback):
+ """
+ This function catches an exception and evaluates it using getException ().
+ Depending on the exception group it just drops the command and message to
+ stderr or writes a complete traceback to stderr.
+ """
+ sys.excepthook = sys.__excepthook__
+ (group, name, message, detail) = errors.getException (None, etype, value,
+ traceback)
+
+ if group in ['user', 'admin']:
+ sys.__stderr__.write ("%s: %s\n" % (self.COMMAND, o(message)))
+ sys.__stderr__.write ("%s\n" % \
+ o(u_("For help, type: %s --help") % self.COMMAND))
+ else:
+ sys.stderr.write ("%s\n" % o(detail))
+
Modified: trunk/gnue-common/src/apps/errors.py
===================================================================
--- trunk/gnue-common/src/apps/errors.py 2004-09-02 09:46:27 UTC (rev
6239)
+++ trunk/gnue-common/src/apps/errors.py 2004-09-02 11:47:24 UTC (rev
6240)
@@ -64,12 +64,12 @@
# Return the name of the exception
# ---------------------------------------------------------------------------
- def getName (self):
+ def getName (self, aType = None):
"""
This function returns the name of the exception (i.e. 'FooBarError')
@return: name of the exception as unicode string
"""
- rep = self.name or "%s" % sys.exc_info () [0]
+ rep = self.name or "%s" % (sys.exc_info () [0] or aType)
return self._fmtUnicode (rep.split ('.') [-1])
@@ -77,7 +77,7 @@
# Get the detail of an exception
# ---------------------------------------------------------------------------
- def getDetail (self, count = None):
+ def getDetail (self, count = None, type = None, value = None, trace = None):
"""
This function returns the exception's detail which is a traceback for
gException instances.
@@ -87,7 +87,10 @@
if self.detail is not None:
return self._fmtUnicode (self.detail, i18n.encoding)
- tStack = traceback.format_exception (*sys.exc_info ())
+ if sys.exc_info () == (None, None, None):
+ tStack = traceback.format_exception (type, value, trace)
+ else:
+ tStack = traceback.format_exception (*sys.exc_info ())
if count is not None:
del tStack [1:count + 1]
return self._fmtUnicode ("%s" % string.join (tStack), i18n.encoding)
@@ -202,7 +205,7 @@
# Get a tuple (type, name, message, detail) for the last exception raised
# -----------------------------------------------------------------------------
-def getException (count = None):
+def getException (count = None, aType = None, aValue = None, aTrace = None):
"""
This function creates a tuple (type, name, message, detail) for the last
exception raised. The optional parameter determines the number of lines
@@ -210,11 +213,14 @@
@param count: number of lines to skip in the traceback
@returns: tuple with type, name, message and detail of the last exception.
"""
- (aType, aValue, aTrace) = sys.exc_info ()
+ (sType, sValue, sTrace) = sys.exc_info ()
+ aType = aType or sType
+ aValue = aValue or sValue
+ aTrace = aTrace or sTrace
if isinstance (aValue, gException):
return (aValue.getGroup (), aValue.getName (), aValue.getMessage (),
- aValue.getDetail (count))
+ aValue.getDetail (count, aType, aValue, aTrace))
else:
# Exception was not a descendant of gException, so we construct the tuple
# from the exception information
@@ -222,7 +228,7 @@
if count is not None:
del lines [1:count + 1]
- name = unicode (aType)
+ name = unicode (aType).split ('.') [-1]
message = unicode (aValue)
detail = string.join (lines)
if isinstance (detail, types.StringType):
Modified: trunk/gnue-common/src/datasources/GConnections.py
===================================================================
--- trunk/gnue-common/src/datasources/GConnections.py 2004-09-02 09:46:27 UTC
(rev 6239)
+++ trunk/gnue-common/src/datasources/GConnections.py 2004-09-02 11:47:24 UTC
(rev 6240)
@@ -39,7 +39,7 @@
from ConfigParser import *
import sys, string, copy, netrc
-from gnue.common.apps import GDebug, plugin
+from gnue.common.apps import plugin, errors
from gnue.common.datasources import Exceptions
from gnue.common.datasources import GLoginHandler
from gnue.common.utils.FileUtils import openResource, dyn_import
@@ -54,12 +54,12 @@
# exist in the Connections Definition File.
pass
-class AdapterNotInstalled (Error):
+class AdapterNotInstalled (errors.AdminError):
# Raised if a provider is requested for which
# the python libraries are not installed.
pass
-class DependencyError (Error):
+class DependencyError (errors.AdminError):
# Raised by the dbdrivers if a dependency module is missing
def __init__ (self, modulename, url):
self.modulename = modulename
@@ -69,7 +69,7 @@
message += u_(" You can download it from %s.") % self.url
Error.__init__ (self, message)
-class InvalidFormatError (Error):
+class InvalidFormatError (errors.AdminError):
# Raised if the Connections Definition File is
# in an unreadable format.
pass
@@ -89,13 +89,14 @@
self._authenticatedUsers = {}
self._eventHandler=eventhandler
- GDebug.printMesg(1,'Conn File: "%s"' % location)
+ gDebug (1, 'Conn File: "%s"' % location)
if len(location):
fileHandle = openResource(location)
try:
self._parser.readfp(fileHandle)
+
except DuplicateSectionError:
tmsg = u_("The connections file has duplicate source definitions."
"\n\nFile: %s") % location
@@ -104,7 +105,7 @@
tmsg = u_("The connections file has no source definitions."
"\n\nFile: %s") % location
raise InvalidFormatError, tmsg
- except:
+ except Exception:
tmsg = u_("The connections file cannot be parsed."
"\n\nFile: %s") % location
raise InvalidFormatError, tmsg
@@ -298,7 +299,8 @@
try:
dd = connection.supportedDataObjects[connection_type](connection)
- GDebug.printMesg (1,'Attaching to %s (%s)' % (dd.__class__.__name__,
connection_type))
+ gDebug (1, 'Attaching to %s (%s)' \
+ % (dd.__class__.__name__, connection_type))
return dd
except KeyError:
tmsg = u_("DB Driver '%(connection)s' does not support source type "
@@ -370,11 +372,11 @@
netrcData = netrc.netrc ().authenticators ("'gnue://%s/'" \
% connection_base)
if netrcData is not None:
- GDebug.printMesg (5, 'Read the user\'s .netrc file')
+ gDebug (5, 'Read the user\'s .netrc file')
loginData ['_username'] = netrcData [0][1:-1]
loginData ['_password'] = netrcData [2][1:-1]
- GDebug.printMesg (5, "Found useful stuff for connection %s in "
+ gDebug (5, "Found useful stuff for connection %s in "
"the user\'s .netrc file" % connection_name)
except (IOError, netrc.NetrcParseError, KeyError):
@@ -417,7 +419,7 @@
else:
attempts = 4
- GDebug.printMesg(5,'Getting new data connection to %s' %
connection_name)
+ gDebug (5, 'Getting new data connection to %s' % connection_name)
errortext = None
while attempts:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r6240 - in trunk/gnue-common/src: apps datasources,
johannes <=