mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Started fleshing out reoganization of errors in errors.py (with gettext support)
This commit is contained in:
@@ -241,21 +241,6 @@ class RegistrationError(IPAError):
|
||||
"""
|
||||
|
||||
|
||||
class NameSpaceError(RegistrationError):
|
||||
"""
|
||||
Raised when name is not a valid Python identifier for use for use as
|
||||
the name of NameSpace member.
|
||||
"""
|
||||
msg = 'name %r does not re.match %r'
|
||||
|
||||
def __init__(self, name, regex):
|
||||
self.name = name
|
||||
self.regex = regex
|
||||
|
||||
def __str__(self):
|
||||
return self.msg % (self.name, self.regex)
|
||||
|
||||
|
||||
class SubclassError(RegistrationError):
|
||||
"""
|
||||
Raised when registering a plugin that is not a subclass of one of the
|
||||
|
213
ipalib/errors2.py
Normal file
213
ipalib/errors2.py
Normal file
@@ -0,0 +1,213 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty inmsgion
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Custom exception classes.
|
||||
|
||||
Certain errors can be returned in RPC response to relay some error condition
|
||||
to the caller.
|
||||
|
||||
============= ========================================
|
||||
Error codes Exceptions
|
||||
============= ========================================
|
||||
900 `PublicError`
|
||||
901 `InternalError`
|
||||
902 - 999 *Reserved for future use*
|
||||
1000 - 1999 `AuthenticationError` and its subclasses
|
||||
2000 - 2999 `AuthorizationError` and its subclasses
|
||||
3000 - 3999 `InvocationError` and its subclasses
|
||||
4000 - 4999 `ExecutionError` and its subclasses
|
||||
5000 - 5999 `GenericError` and its subclasses
|
||||
============= ========================================
|
||||
"""
|
||||
|
||||
from inspect import isclass
|
||||
import request
|
||||
|
||||
|
||||
class PrivateError(StandardError):
|
||||
"""
|
||||
Base class for exceptions that are *never* returned in an RPC response.
|
||||
"""
|
||||
|
||||
|
||||
class PublicError(StandardError):
|
||||
"""
|
||||
**900** Base class for exceptions that can be returned in an RPC response.
|
||||
"""
|
||||
|
||||
code = 900
|
||||
|
||||
def __init__(self, message=None, **kw):
|
||||
self.kw = kw
|
||||
if message is None:
|
||||
message = self.get_format(request._) % kw
|
||||
StandardError.__init__(self, message)
|
||||
|
||||
def get_format(self, _):
|
||||
return _('')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class InternalError(PublicError):
|
||||
"""
|
||||
**901** Used to conceal a non-public exception.
|
||||
"""
|
||||
|
||||
code = 901
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
# 1000 - 1999: Authentication Errors
|
||||
class AuthenticationError(PublicError):
|
||||
"""
|
||||
**1000** Base class for authentication errors (*1000 - 1999*).
|
||||
"""
|
||||
|
||||
code = 1000
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
# 2000 - 2999: Authorization Errors
|
||||
class AuthorizationError(PublicError):
|
||||
"""
|
||||
**2000** Base class for authorization errors (*2000 - 2999*).
|
||||
"""
|
||||
|
||||
code = 2000
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
# 3000 - 3999: Invocation Errors
|
||||
|
||||
class InvocationError(PublicError):
|
||||
"""
|
||||
**3000** Base class for command invocation errors (*3000 - 3999*).
|
||||
"""
|
||||
|
||||
code = 3000
|
||||
|
||||
|
||||
class CommandError(InvocationError):
|
||||
"""
|
||||
**3001** Raised when an unknown command is called.
|
||||
"""
|
||||
|
||||
code = 3001
|
||||
|
||||
def get_format(self, _):
|
||||
return _('Unknown command %(name)r')
|
||||
|
||||
|
||||
class RemoteCommandError(InvocationError):
|
||||
"""
|
||||
**3002** Raised when client receives a `CommandError` from server.
|
||||
"""
|
||||
|
||||
code = 3002
|
||||
|
||||
|
||||
class ArgumentError(InvocationError):
|
||||
"""
|
||||
**3003** Raised when a command is called with wrong number of arguments.
|
||||
"""
|
||||
|
||||
code = 3003
|
||||
|
||||
|
||||
class OptionError(InvocationError):
|
||||
"""
|
||||
**3004** Raised when a command is called with unknown options.
|
||||
"""
|
||||
|
||||
code = 3004
|
||||
|
||||
|
||||
class RequirementError(InvocationError):
|
||||
"""
|
||||
**3005** Raised when a required parameter is not provided.
|
||||
"""
|
||||
|
||||
code = 3005
|
||||
|
||||
|
||||
class ConversionError(InvocationError):
|
||||
"""
|
||||
**3006** Raised when a parameter value is the wrong type.
|
||||
"""
|
||||
|
||||
code = 3006
|
||||
|
||||
|
||||
class ValidationError(InvocationError):
|
||||
"""
|
||||
**3007** Raised when a parameter value fails a validation rule.
|
||||
"""
|
||||
|
||||
code = 3007
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
# 4000 - 4999: Execution Errors
|
||||
|
||||
class ExecutionError(PublicError):
|
||||
"""
|
||||
**4000** Base class for execution/operation errors (*4000 - 4999*).
|
||||
"""
|
||||
|
||||
code = 4000
|
||||
|
||||
|
||||
|
||||
##############################################################################
|
||||
# 5000 - 5999: Generic Errors
|
||||
|
||||
class GenericError(PublicError):
|
||||
"""
|
||||
**5000** Errors inappropriate for other categories (*5000 - 5999*).
|
||||
"""
|
||||
|
||||
code = 5000
|
||||
|
||||
|
||||
|
||||
def __errors_iter():
|
||||
"""
|
||||
Iterate through all the `PublicError` subclasses.
|
||||
"""
|
||||
for (key, value) in globals().items():
|
||||
if key.startswith('_') or not isclass(value):
|
||||
continue
|
||||
if issubclass(value, PublicError):
|
||||
yield value
|
||||
|
||||
public_errors = tuple(
|
||||
sorted(__errors_iter(), key=lambda E: E.code)
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
for klass in public_errors:
|
||||
print '%d\t%s' % (klass.code, klass.__name__)
|
||||
print '(%d public errors)' % len(public_errors)
|
@@ -416,6 +416,13 @@ class Param(ReadOnly):
|
||||
'%s.%s()' % (self.__class__.__name__, '_convert_scalar')
|
||||
)
|
||||
|
||||
def validate(self, value):
|
||||
"""
|
||||
Check validity of ``value``.
|
||||
|
||||
:param value: A proposed value for this parameter.
|
||||
"""
|
||||
|
||||
|
||||
class Bool(Param):
|
||||
"""
|
||||
|
@@ -32,6 +32,12 @@ from constants import OVERRIDE_ERROR
|
||||
context = threading.local()
|
||||
|
||||
|
||||
def _(message):
|
||||
if hasattr(context, 'gettext'):
|
||||
return context.gettext(message)
|
||||
return message.decode('UTF-8')
|
||||
|
||||
|
||||
def set_languages(*languages):
|
||||
if hasattr(context, 'languages'):
|
||||
raise StandardError(OVERRIDE_ERROR %
|
||||
|
41
tests/test_ipalib/test_error2.py
Normal file
41
tests/test_ipalib/test_error2.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Test the `ipalib.error2` module.
|
||||
"""
|
||||
|
||||
import re
|
||||
import inspect
|
||||
from ipalib import errors2
|
||||
|
||||
|
||||
def test_public_errors():
|
||||
"""
|
||||
Test the `ipalib.errors2.public_errors` module variable.
|
||||
"""
|
||||
for klass in errors2.public_errors:
|
||||
assert issubclass(klass, errors2.PublicError)
|
||||
assert not issubclass(klass, errors2.PrivateError)
|
||||
assert type(klass.code) is int
|
||||
assert 900 <= klass.code <= 5999
|
||||
doc = inspect.getdoc(klass)
|
||||
m = re.match(r'^\*{2}(\d+)\*{2} ', doc)
|
||||
assert m is not None, doc
|
||||
assert int(m.group(1)) == klass.code, klass.__name__
|
Reference in New Issue
Block a user