RIFT OSM R1 Initial Submission
[osm/SO.git] / common / python / rift / mano / yang_translator / common / exception.py
1
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16 #
17
18 '''
19 Exceptions for the YANG Translator package.
20 '''
21
22 import logging
23 import sys
24 import traceback
25
26 from rift.mano.yang_translator.common.utils import _
27
28 log = logging.getLogger(__name__)
29
30
31 class YANGException(Exception):
32 '''Base exception class for YANG
33
34 To correctly use this class, inherit from it and define
35 a 'msg_fmt' property.
36
37 '''
38
39 _FATAL_EXCEPTION_FORMAT_ERRORS = False
40
41 message = _('An unknown exception occurred.')
42
43 def __init__(self, **kwargs):
44 try:
45 self.message = self.msg_fmt % kwargs
46 except KeyError:
47 exc_info = sys.exc_info()
48 log.exception(_('Exception in string format operation: %s')
49 % exc_info[1])
50
51 if YANGException._FATAL_EXCEPTION_FORMAT_ERRORS:
52 raise exc_info[0]
53
54 def __str__(self):
55 return self.message
56
57 @staticmethod
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,
63 "attr": attr,
64 "value1": value,
65 "value2": valid_values})
66 ExceptionCollector.appendException(
67 InvalidSchemaError(message=msg))
68
69 @staticmethod
70 def set_fatal_format_exception(flag):
71 if isinstance(flag, bool):
72 YANGException._FATAL_EXCEPTION_FORMAT_ERRORS = flag
73
74
75 class MissingRequiredFieldError(YANGException):
76 msg_fmt = _('%(what)s is missing required field "%(required)s".')
77
78
79 class UnknownFieldError(YANGException):
80 msg_fmt = _('%(what)s contains unknown field "%(field)s". Refer to the '
81 'definition to verify valid values.')
82
83
84 class TypeMismatchError(YANGException):
85 msg_fmt = _('%(what)s must be of type "%(type)s".')
86
87
88 class InvalidNodeTypeError(YANGException):
89 msg_fmt = _('Node type "%(what)s" is not a valid type.')
90
91
92 class InvalidTypeError(YANGException):
93 msg_fmt = _('Type "%(what)s" is not a valid type.')
94
95
96 class InvalidSchemaError(YANGException):
97 msg_fmt = _('%(message)s')
98
99
100 class ValidationError(YANGException):
101 msg_fmt = _('%(message)s')
102
103
104 class UnknownInputError(YANGException):
105 msg_fmt = _('Unknown input "%(input_name)s".')
106
107
108 class InvalidPropertyValueError(YANGException):
109 msg_fmt = _('Value of property "%(what)s" is invalid.')
110
111
112 class InvalidTemplateVersion(YANGException):
113 msg_fmt = _('The template version "%(what)s" is invalid. '
114 'Valid versions are "%(valid_versions)s".')
115
116
117 class InvalidYANGVersionPropertyException(YANGException):
118 msg_fmt = _('Value of YANG version property "%(what)s" is invalid.')
119
120
121 class URLException(YANGException):
122 msg_fmt = _('%(what)s')
123
124
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.')
129
130
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.')
135
136
137 class InvalidGroupTargetException(YANGException):
138 msg_fmt = _('"%(message)s"')
139
140
141 class ConfFileParseError(YANGException):
142 msg_fmt = _('%(message)s')
143
144
145 class ConfOptionNotDefined(YANGException):
146 msg_fmt = _('Option %(key)s in section %(section)s '
147 'is not defined in conf file')
148
149
150 class ConfSectionNotDefined(YANGException):
151 msg_fmt = _('Section %(section)s is not defined in conf file')
152
153
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.')
158
159
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.')
164
165
166 class YangClassAttributeError(YANGException):
167 msg_fmt = _('Class attribute referenced not found. '
168 '%(message)s. Check to see that it is defined.')
169
170
171 class ExceptionCollector(object):
172
173 exceptions = []
174 collecting = False
175
176 @staticmethod
177 def clear():
178 del ExceptionCollector.exceptions[:]
179
180 @staticmethod
181 def start():
182 ExceptionCollector.clear()
183 ExceptionCollector.collecting = True
184
185 @staticmethod
186 def stop():
187 ExceptionCollector.collecting = False
188
189 @staticmethod
190 def contains(exception):
191 for ex in ExceptionCollector.exceptions:
192 if str(ex) == str(exception):
193 return True
194 return False
195
196 @staticmethod
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)
202 else:
203 raise exception
204
205 @staticmethod
206 def exceptionsCaught():
207 return len(ExceptionCollector.exceptions) > 0
208
209 @staticmethod
210 def getTraceString(traceList):
211 traceString = ''
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})
217 return traceString
218
219 @staticmethod
220 def getExceptionReportEntry(exception, full=True):
221 entry = exception.__class__.__name__ + ': ' + str(exception)
222 if full:
223 entry += '\n' + ExceptionCollector.getTraceString(exception.trace)
224 return entry
225
226 @staticmethod
227 def getExceptions():
228 return ExceptionCollector.exceptions
229
230 @staticmethod
231 def getExceptionsReport(full=True):
232 report = []
233 for exception in ExceptionCollector.exceptions:
234 report.append(
235 ExceptionCollector.getExceptionReportEntry(exception, full))
236 return report
237
238 @staticmethod
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})