3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
19 Exceptions for the YANG Translator package.
26 from rift
.mano
.yang_translator
.common
.utils
import _
28 log
= logging
.getLogger(__name__
)
31 class YANGException(Exception):
32 '''Base exception class for YANG
34 To correctly use this class, inherit from it and define
39 _FATAL_EXCEPTION_FORMAT_ERRORS
= False
41 message
= _('An unknown exception occurred.')
43 def __init__(self
, **kwargs
):
45 self
.message
= self
.msg_fmt
% kwargs
47 exc_info
= sys
.exc_info()
48 log
.exception(_('Exception in string format operation: %s')
51 if YANGException
._FATAL
_EXCEPTION
_FORMAT
_ERRORS
:
58 def generate_inv_schema_property_error(self
, attr
, value
, valid_values
):
59 msg
= (_('Schema definition of "%(propname)s" has '
60 '"%(attr)s" attribute with invalid value '
61 '"%(value1)s". The value must be one of '
62 '"%(value2)s".') % {"propname": self
.name
,
65 "value2": valid_values
})
66 ExceptionCollector
.appendException(
67 InvalidSchemaError(message
=msg
))
70 def set_fatal_format_exception(flag
):
71 if isinstance(flag
, bool):
72 YANGException
._FATAL
_EXCEPTION
_FORMAT
_ERRORS
= flag
75 class MissingRequiredFieldError(YANGException
):
76 msg_fmt
= _('%(what)s is missing required field "%(required)s".')
79 class UnknownFieldError(YANGException
):
80 msg_fmt
= _('%(what)s contains unknown field "%(field)s". Refer to the '
81 'definition to verify valid values.')
84 class TypeMismatchError(YANGException
):
85 msg_fmt
= _('%(what)s must be of type "%(type)s".')
88 class InvalidNodeTypeError(YANGException
):
89 msg_fmt
= _('Node type "%(what)s" is not a valid type.')
92 class InvalidTypeError(YANGException
):
93 msg_fmt
= _('Type "%(what)s" is not a valid type.')
96 class InvalidSchemaError(YANGException
):
97 msg_fmt
= _('%(message)s')
100 class ValidationError(YANGException
):
101 msg_fmt
= _('%(message)s')
104 class UnknownInputError(YANGException
):
105 msg_fmt
= _('Unknown input "%(input_name)s".')
108 class InvalidPropertyValueError(YANGException
):
109 msg_fmt
= _('Value of property "%(what)s" is invalid.')
112 class InvalidTemplateVersion(YANGException
):
113 msg_fmt
= _('The template version "%(what)s" is invalid. '
114 'Valid versions are "%(valid_versions)s".')
117 class InvalidYANGVersionPropertyException(YANGException
):
118 msg_fmt
= _('Value of YANG version property "%(what)s" is invalid.')
121 class URLException(YANGException
):
122 msg_fmt
= _('%(what)s')
125 class YangExtImportError(YANGException
):
126 msg_fmt
= _('Unable to import extension "%(ext_name)s". '
127 'Check to see that it exists and has no '
128 'language definition errors.')
131 class YangExtAttributeError(YANGException
):
132 msg_fmt
= _('Missing attribute in extension "%(ext_name)s". '
133 'Check to see that it has required attributes '
134 '"%(attrs)s" defined.')
137 class InvalidGroupTargetException(YANGException
):
138 msg_fmt
= _('"%(message)s"')
141 class ConfFileParseError(YANGException
):
142 msg_fmt
= _('%(message)s')
145 class ConfOptionNotDefined(YANGException
):
146 msg_fmt
= _('Option %(key)s in section %(section)s '
147 'is not defined in conf file')
150 class ConfSectionNotDefined(YANGException
):
151 msg_fmt
= _('Section %(section)s is not defined in conf file')
154 class YangModImportError(YANGException
):
155 msg_fmt
= _('Unable to import module %(mod_name)s. '
156 'Check to see that it exists and has no '
157 'language definition errors.')
160 class YangClassImportError(YANGException
):
161 msg_fmt
= _('Unable to import class %(name)s in '
162 'module %(mod_name)s. Check to see that it '
163 'exists and has no language definition errors.')
166 class YangClassAttributeError(YANGException
):
167 msg_fmt
= _('Class attribute referenced not found. '
168 '%(message)s. Check to see that it is defined.')
171 class ExceptionCollector(object):
178 del ExceptionCollector
.exceptions
[:]
182 ExceptionCollector
.clear()
183 ExceptionCollector
.collecting
= True
187 ExceptionCollector
.collecting
= False
190 def contains(exception
):
191 for ex
in ExceptionCollector
.exceptions
:
192 if str(ex
) == str(exception
):
197 def appendException(exception
):
198 if ExceptionCollector
.collecting
:
199 if not ExceptionCollector
.contains(exception
):
200 exception
.trace
= traceback
.extract_stack()[:-1]
201 ExceptionCollector
.exceptions
.append(exception
)
206 def exceptionsCaught():
207 return len(ExceptionCollector
.exceptions
) > 0
210 def getTraceString(traceList
):
212 for entry
in traceList
:
213 f
, l
, m
, c
= entry
[0], entry
[1], entry
[2], entry
[3]
214 traceString
+= (_('\t\tFile %(file)s, line %(line)s, in '
215 '%(method)s\n\t\t\t%(call)s\n')
216 % {'file': f
, 'line': l
, 'method': m
, 'call': c
})
220 def getExceptionReportEntry(exception
, full
=True):
221 entry
= exception
.__class
__.__name
__ + ': ' + str(exception
)
223 entry
+= '\n' + ExceptionCollector
.getTraceString(exception
.trace
)
228 return ExceptionCollector
.exceptions
231 def getExceptionsReport(full
=True):
233 for exception
in ExceptionCollector
.exceptions
:
235 ExceptionCollector
.getExceptionReportEntry(exception
, full
))
239 def assertExceptionMessage(exception
, message
):
240 err_msg
= exception
.__name
__ + ': ' + message
241 report
= ExceptionCollector
.getExceptionsReport(False)
242 assert err_msg
in report
, (_('Could not find "%(msg)s" in "%(rep)s".')
243 % {'rep': report
.__str
__(), 'msg': err_msg
})