Go to the documentation of this file.00001 """
00002 Define exceptions to be raised at various places in the stack
00003 """
00004
00005 from opcua.compat import with_metaclass
00006
00007 class _AutoRegister(type):
00008 def __new__(mcs, name, bases, dict):
00009 SubClass = type.__new__(mcs, name, bases, dict)
00010
00011
00012 for base in bases:
00013 try:
00014 subclasses = base._subclasses
00015 code = dict['code']
00016 except (AttributeError, KeyError):
00017 pass
00018 else:
00019 subclasses[code] = SubClass
00020
00021 return SubClass
00022
00023 class UaError(RuntimeError):
00024 pass
00025
00026
00027 class UaStatusCodeError(with_metaclass(_AutoRegister, UaError)):
00028 """
00029 This exception is raised when a bad status code is encountered.
00030
00031 It exposes the status code number in the `code' property, so the
00032 user can distinguish between the different status codes and maybe
00033 handle some of them.
00034
00035 The list of status error codes can be found in opcua.ua.status_codes.
00036 """
00037
00038 """ Dict containing all subclasses keyed to their status code. """
00039 _subclasses = {}
00040
00041 def __new__(cls, *args):
00042 """
00043 Creates a new UaStatusCodeError but returns a more specific subclass
00044 if possible, e.g.
00045
00046 UaStatusCodeError(0x80010000) => BadUnexpectedError()
00047 """
00048
00049
00050 if len(args) >= 1:
00051 code = args[0]
00052 try:
00053 cls = cls._subclasses[code]
00054 except (KeyError, AttributeError):
00055 pass
00056 else:
00057 args = args[1:]
00058
00059 return UaError.__new__(cls, *args)
00060
00061 def __init__(self, code=None):
00062 """
00063 :param code: The code of the exception. Only needed when not instanciating
00064 a concrete subclass such as BadInternalError.
00065 """
00066 if code is None:
00067 if type(self) is UaStatusCodeError:
00068 raise TypeError("UaStatusCodeError(code) cannot be instantiated without a status code.")
00069 UaError.__init__(self, code)
00070
00071 def __str__(self):
00072
00073 import opcua.ua.status_codes as status_codes
00074
00075 return "{1}({0})".format(*status_codes.get_name_and_doc(self.code))
00076
00077 @property
00078 def code(self):
00079 """
00080 The code of the status error.
00081 """
00082 return self.args[0]
00083
00084 class UaStringParsingError(UaError):
00085 pass