blob: 1dba529e873560588e5d3cd4434a6fd36301b09c [file] [log] [blame]
#
# -*- coding: utf-8 -*-
#
# This file is part of reclass (http://github.com/madduck/reclass)
#
# Copyright © 2007–13 martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
import posix, sys
import traceback
from reclass.defaults import PARAMETER_INTERPOLATION_SENTINELS
class ReclassException(Exception):
def __init__(self, msg, rc=posix.EX_SOFTWARE, *args):
super(ReclassException, self).__init__(msg, *args)
self._rc = rc
self._traceback = traceback.format_exc()
def __str__(self):
return self.message
rc = property(lambda self: self._rc)
def exit_with_message(self, out=sys.stderr):
print >>out, self.message
print >>out, self._traceback
sys.exit(self.rc)
class PermissionError(ReclassException):
def __init__(self, msg, rc=posix.EX_NOPERM):
super(PermissionError, self).__init__(msg, rc)
class InvocationError(ReclassException):
def __init__(self, msg, rc=posix.EX_USAGE):
super(InvocationError, self).__init__(msg, rc)
class ConfigError(ReclassException):
def __init__(self, msg, rc=posix.EX_CONFIG):
super(ConfigError, self).__init__(msg, rc)
class DuplicateUriError(ConfigError):
def __init__(self, nodes_uri, classes_uri):
msg = "The inventory URIs must not be the same for nodes and classes: "
msg += nodes_uri
super(DuplicateUriError, self).__init__(msg)
class UriOverlapError(ConfigError):
def __init__(self, nodes_uri, classes_uri):
msg = "The URIs for the nodes and classes inventories must not " \
"overlap, but {0} and {1} do."
msg = msg.format(nodes_uri, classes_uri)
super(UriOverlapError, self).__init__(msg)
class NotFoundError(ReclassException):
def __init__(self, msg, rc=posix.EX_IOERR):
super(NotFoundError, self).__init__(msg, rc)
class NodeNotFound(NotFoundError):
def __init__(self, storage, nodename, uri):
self._storage = storage
self._name = nodename
self._uri = uri
msg = "Node '{0}' not found under {1}://{2}".format(self._name,
self._storage,
self._uri)
super(NodeNotFound, self).__init__(msg)
class ClassNotFound(NotFoundError):
def __init__(self, storage, classname, uri, nodename):
self._storage = storage
self._name = classname
self._uri = uri
self._nodename = nodename
msg = "Class '{0}' (in ancestry of node '{1}') not found under {2}://{3}" \
.format(self._name, self._nodename, self._storage, self._uri)
super(ClassNotFound, self).__init__(msg)
class InterpolationError(ReclassException):
def __init__(self, msg, rc=posix.EX_DATAERR):
super(InterpolationError, self).__init__(msg, rc)
class UndefinedVariableError(InterpolationError):
def __init__(self, var, context=None):
self._var = var
msg = "Cannot resolve " + var.join(PARAMETER_INTERPOLATION_SENTINELS)
if context:
msg += ' in the context of %s' % context
super(UndefinedVariableError, self).__init__(msg)
var = property(lambda x: x._var)
class IncompleteInterpolationError(InterpolationError):
def __init__(self, string, end_sentinel):
msg = "Missing '%s' to end reference: %s" % \
(end_sentinel, string.join(PARAMETER_INTERPOLATION_SENTINELS))
super(IncompleteInterpolationError, self).__init__(msg)
class InfiniteRecursionError(InterpolationError):
def __init__(self, path, ref):
msg = "Infinite recursion while resolving %s at %s" \
% (ref.join(PARAMETER_INTERPOLATION_SENTINELS), path)
super(InfiniteRecursionError, self).__init__(msg)
class MappingError(ReclassException):
def __init__(self, msg, rc=posix.EX_DATAERR):
super(MappingError, self).__init__(msg, rc)
class MappingFormatError(MappingError):
def __init__(self, msg):
super(MappingFormatError, self).__init__(msg)
class NameError(ReclassException):
def __init__(self, msg, rc=posix.EX_DATAERR):
super(NameError, self).__init__(msg, rc)
class InvalidClassnameError(NameError):
def __init__(self, invalid_character, classname):
self._invalid_character = invalid_character
self._classname = classname
msg = "Invalid character '{0}' in class name '{1}'."
msg = msg.format(invalid_character, classname)
super(InvalidClassnameError, self).__init__(msg)
class DuplicateNodeNameError(NameError):
def __init__(self, storage, name, uri1, uri2):
msg = "{0}: Definition of node '{1}' in '{2}' collides with " \
"definition in '{3}'. Nodes can only be defined once per inventory."
msg = msg.format(storage, name, uri2, uri1)
super(DuplicateNodeNameError, self).__init__(msg)