1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 # not use this file except in compliance with the License. You may obtain
3 # a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 # License for the specific language governing permissions and limitations
14 TOSCA exception classes
20 from toscaparser.utils.gettextutils import _
23 log = logging.getLogger('tosca')
26 class TOSCAException(Exception):
27 '''Base exception class for TOSCA
29 To correctly use this class, inherit from it and define
34 _FATAL_EXCEPTION_FORMAT_ERRORS = False
36 message = _('An unknown exception occurred.')
38 def __init__(self, **kwargs):
40 self.message = self.msg_fmt % kwargs
42 exc_info = sys.exc_info()
43 log.exception(_('Exception in string format operation: %s')
46 if TOSCAException._FATAL_EXCEPTION_FORMAT_ERRORS:
53 def generate_inv_schema_property_error(self, attr, value, valid_values):
54 msg = (_('Schema definition of "%(propname)s" has '
55 '"%(attr)s" attribute with invalid value '
56 '"%(value1)s". The value must be one of '
57 '"%(value2)s".') % {"propname": self.name,
60 "value2": valid_values})
61 ExceptionCollector.appendException(
62 InvalidSchemaError(message=msg))
65 def set_fatal_format_exception(flag):
66 if isinstance(flag, bool):
67 TOSCAException._FATAL_EXCEPTION_FORMAT_ERRORS = flag
70 class UnsupportedTypeError(TOSCAException):
71 msg_fmt = _('Type "%(what)s" is valid TOSCA type'
72 ' but not supported at this time.')
75 class MissingRequiredFieldError(TOSCAException):
76 msg_fmt = _('%(what)s is missing required field "%(required)s".')
79 class UnknownFieldError(TOSCAException):
80 msg_fmt = _('%(what)s contains unknown field "%(field)s". Refer to the '
81 'definition to verify valid values.')
84 class TypeMismatchError(TOSCAException):
85 msg_fmt = _('%(what)s must be of type "%(type)s".')
88 class InvalidNodeTypeError(TOSCAException):
89 msg_fmt = _('Node type "%(what)s" is not a valid type.')
92 class InvalidTypeError(TOSCAException):
93 msg_fmt = _('Type "%(what)s" is not a valid type.')
96 class InvalidTypeAdditionalRequirementsError(TOSCAException):
97 msg_fmt = _('Additional requirements for type "%(type)s" not met.')
100 class RangeValueError(TOSCAException):
101 msg_fmt = _('The value "%(pvalue)s" of property "%(pname)s" is out of '
102 'range "(min:%(vmin)s, max:%(vmax)s)".')
105 class InvalidSchemaError(TOSCAException):
106 msg_fmt = _('%(message)s')
109 class ValidationError(TOSCAException):
110 msg_fmt = _('%(message)s')
113 class UnknownInputError(TOSCAException):
114 msg_fmt = _('Unknown input "%(input_name)s".')
117 class UnknownOutputError(TOSCAException):
118 msg_fmt = _('Unknown output "%(output_name)s" in %(where)s.')
121 class MissingRequiredInputError(TOSCAException):
122 msg_fmt = _('%(what)s is missing required input definition '
123 'of input "%(input_name)s".')
126 class MissingRequiredParameterError(TOSCAException):
127 msg_fmt = _('%(what)s is missing required parameter for input '
131 class MissingDefaultValueError(TOSCAException):
132 msg_fmt = _('%(what)s is missing required default value '
133 'of input "%(input_name)s".')
136 class MissingRequiredOutputError(TOSCAException):
137 msg_fmt = _('%(what)s is missing required output definition '
138 'of output "%(output_name)s".')
141 class InvalidPropertyValueError(TOSCAException):
142 msg_fmt = _('Value of property "%(what)s" is invalid.')
145 class InvalidTemplateVersion(TOSCAException):
146 msg_fmt = _('The template version "%(what)s" is invalid. '
147 'Valid versions are "%(valid_versions)s".')
150 class InvalidTOSCAVersionPropertyException(TOSCAException):
151 msg_fmt = _('Value of TOSCA version property "%(what)s" is invalid.')
154 class URLException(TOSCAException):
155 msg_fmt = _('%(what)s')
158 class ToscaExtImportError(TOSCAException):
159 msg_fmt = _('Unable to import extension "%(ext_name)s". '
160 'Check to see that it exists and has no '
161 'language definition errors.')
164 class ToscaExtAttributeError(TOSCAException):
165 msg_fmt = _('Missing attribute in extension "%(ext_name)s". '
166 'Check to see that it has required attributes '
167 '"%(attrs)s" defined.')
170 class InvalidGroupTargetException(TOSCAException):
171 msg_fmt = _('"%(message)s"')
174 class ExceptionCollector(object):
181 del ExceptionCollector.exceptions[:]
185 ExceptionCollector.clear()
186 ExceptionCollector.collecting = True
190 ExceptionCollector.collecting = False
193 def contains(exception):
194 for ex in ExceptionCollector.exceptions:
195 if str(ex) == str(exception):
200 def appendException(exception):
201 if ExceptionCollector.collecting:
202 if not ExceptionCollector.contains(exception):
203 exception.trace = traceback.extract_stack()[:-1]
204 ExceptionCollector.exceptions.append(exception)
209 def removeException(exception_type):
210 # if ExceptionCollector.collecting and ExceptionCollector.exceptions:
211 if ExceptionCollector.exceptions:
213 for i, e in enumerate(ExceptionCollector.exceptions):
214 if not isinstance(e, exception_type):
215 tmp_exceptions.append(e)
216 # del ExceptionCollector.exceptions[i]
217 ExceptionCollector.exceptions = tmp_exceptions
220 def exceptionsCaught():
221 return len(ExceptionCollector.exceptions) > 0
224 def getTraceString(traceList):
226 for entry in traceList:
227 f, l, m, c = entry[0], entry[1], entry[2], entry[3]
228 traceString += (_('\t\tFile %(file)s, line %(line)s, in '
229 '%(method)s\n\t\t\t%(call)s\n')
230 % {'file': f, 'line': l, 'method': m, 'call': c})
234 def getExceptionReportEntry(exception, full=True):
235 entry = exception.__class__.__name__ + ': ' + str(exception)
237 entry += '\n' + ExceptionCollector.getTraceString(exception.trace)
242 return ExceptionCollector.exceptions
245 def getExceptionsReport(full=True):
247 for exception in ExceptionCollector.exceptions:
249 ExceptionCollector.getExceptionReportEntry(exception, full))
253 def assertExceptionMessage(exception, message):
254 err_msg = exception.__name__ + ': ' + message
255 report = ExceptionCollector.getExceptionsReport(False)
256 assert err_msg in report, (_('Could not find "%(msg)s" in "%(rep)s".')
257 % {'rep': report.__str__(), 'msg': err_msg})