Package gavo :: Package utils :: Module excs
[frames] | no frames]

Source Code for Module gavo.utils.excs

  1  """  
  2  Global exceptions for the GAVO data center software. 
  3   
  4  All exceptions escaping modules should inherit from Error in some way. 
  5  Exceptions orginating in only one module should usually be defined there, 
  6  exceptions should only be defined here if they are raised by more than 
  7  one module. 
  8   
  9  Of course, for certain errors, built-in exceptions (e.g., NotImplemented 
 10  or so) may be raised and propagated as well, but these should always 
 11  signify internal bugs, never things a user should be confronted with 
 12  under normal circumstances. 
 13   
 14  And then there's stuff like fancyconfig that's supposed to live 
 15  independently of the rest.  It's ok if those raise other Exceptions, 
 16  but clearly there shouldn't be many of those, or error reporting will 
 17  become an even worse nightmare than it already is. 
 18  """ 
 19   
 20   
 21  #c Copyright 2008-2019, the GAVO project 
 22  #c 
 23  #c This program is free software, covered by the GNU GPL.  See the 
 24  #c COPYING file in the source distribution. 
 25   
 26   
 27  # NOTE -- due to a bug in python 2.5, you need to set the args attribute 
 28  # in your constructors, or else they'll bomb on unpickling 
 29   
 30  from gavo.utils.fancyconfig import NoConfigItem #noflake: exported name 
 31   
 32   
33 -class Error(Exception):
34 """The base class for all exceptions that can be expected to escape 35 a module. 36 37 Apart from the normal message, you can give a ``hint`` constructor argument. 38 """
39 - def __init__(self, msg="", hint=None):
40 Exception.__init__(self, msg) 41 self.args = [msg, hint] 42 self.msg = msg 43 self.hint = hint
44
45 - def __str__(self):
46 return self.msg
47 48
49 -class StructureError(Error):
50 """is raised if an error occurs during the construction of 51 structures. 52 53 You can construct these with pos; this is an opaque object that, when 54 stringified, should expand to something that gives the user a rough idea 55 of where something went wrong. 56 57 Since you will usually not know where you are in the source document 58 when you want to raise a StructureError, xmlstruct will try 59 to fill pos in when it's still None when it sees a StructureError. 60 Thus, you're probably well advised to leave it blank. 61 """
62 - def __init__(self, msg, pos=None, hint=None):
63 Error.__init__(self, msg, hint=hint) 64 self.args = [msg, pos, hint] 65 self.pos = pos
66
67 - def addPos(self, baseMsg):
68 if self.pos is None: 69 return baseMsg 70 else: 71 return "At %s: %s"%(str(self.pos), baseMsg)
72
73 - def __str__(self):
74 return self.addPos(self.msg)
75 76
77 -class LiteralParseError(StructureError):
78 """is raised if an attribute literal is somehow bad. 79 80 LiteralParseErrors are constructed with the name of the attribute 81 that was being parsed, the offending literal, and optionally a 82 parse position and a hint. 83 """
84 - def __init__(self, attName, literal, pos=None, hint=None):
85 StructureError.__init__(self, literal, pos=pos, hint=hint) 86 self.args = [attName, literal, pos, hint] 87 self.attName, self.literal = attName, literal
88
89 - def __str__(self):
90 return self.addPos( 91 "'%s' is not a valid value for %s"%(self.literal, self.attName))
92 93
94 -class RestrictedElement(StructureError):
95 """is raised when elements forbidden in restricted RDs are encountered 96 when restricted parsing is in effect. 97 """
98 - def __init__(self, elName, pos=None, hint=None):
99 if hint is None: 100 hint='If you are actually sure this RD is what you think it it,' 101 ' you could always gavo imp it from the command line' 102 StructureError.__init__(self, "Illegal: "+elName, pos=pos, hint=hint) 103 self.args = [elName, pos, hint] 104 self.elName = elName
105
106 - def __str__(self):
107 return self.addPos("'%s' is an illegal attribute or element" 108 " when parsing from untrusted sources."%self.elName)
109 110
111 -class BadCode(StructureError):
112 """is raised when some code could not be compiled. 113 114 BadCodes are constructed with the offending code, a code type, 115 the original exception, and optionally a hint and a position. 116 """
117 - def __init__(self, code, codeType, origExc, hint=None, pos=None):
118 if not hint: 119 hint = "The offending code was:\n%s"%code 120 StructureError.__init__(self, "Bad code", pos=pos, hint=hint) 121 self.args = [code, codeType, origExc, hint, pos] 122 self.code, self.codeType = code, codeType 123 self.origExc = origExc
124
125 - def __repr__(self):
126 return self.addPos( 127 "Bad source code in %s (%s)"%( 128 self.codeType, unicode(self.origExc)))
129
130 - def __str__(self):
131 return repr(self)
132 133
134 -class ValidationError(Error):
135 """is raised when the validation of a field fails. 136 137 ValidationErrors are constructed with a message, a column name, 138 and optionally a row (i.e., a dict) and a hint. 139 """
140 - def __init__(self, msg, colName, row=None, hint=None):
141 Error.__init__(self, msg, hint=hint) 142 self.args = [msg, colName, row, hint] 143 self.msg = msg 144 self.colName, self.row = colName, row
145
146 - def __str__(self):
147 recStr = "" 148 # if self.row: 149 # recStr = ", found in: row %s"%repr(self.row) 150 if self.colName: 151 return "Field %s: %s%s"%(self.colName, self.msg, recStr) 152 else: 153 return "Unidentified Field: %s%s"%(self.msg, recStr)
154 155 __unicode__ = __str__
156 157
158 -class MultiplicityError(ValidationError):
159 """is raised when a singleton is passed in multiple times or vice versa. 160 """
161
162 -class SourceParseError(Error):
163 """is raised when some syntax error occurs during a source parse. 164 165 They are constructed with the offending input construct (a source line 166 or similar, None in a pinch) and the result of the row iterator's getLocator 167 call. 168 """
169 - def __init__(self, msg, offending=None, location="unspecified location", 170 source="<unspecified source>", hint=None):
171 Error.__init__(self, msg, hint=hint) 172 self.args = [msg, offending, location, source] 173 self.offending, self.location = offending, location 174 self.source = source
175
176 - def __str__(self):
177 if self.offending: 178 return "At %s: %s, offending %s"%(self.location, self.msg, 179 self.offending) 180 else: 181 return "At %s: %s"%(self.location, self.msg)
182 183
184 -class DataError(Error):
185 """is raised when something is wrong with a data set. 186 187 When facing the web, these yield HTTP status 406. 188 """
189 190
191 -class ReportableError(Error):
192 """is raised when something decides it can come up with an error message 193 that should be presented to the user as-is. 194 195 UIs should, consequently, just dump the payload and not try adornments. 196 The content should be treated as a unicode string. 197 """
198 199
200 -class NotFoundError(Error):
201 """is raised when something is asked for something that does not exist. 202 203 lookedFor can be an arbitrary object, so be careful when your repr it -- 204 that may be long. 205 """
206 - def __init__(self, lookedFor, what, within, hint=None):
207 Error.__init__(self, "ignored", hint=hint) 208 self.args = [lookedFor, what, within, hint] 209 self.lookedFor, self.what = lookedFor, what 210 self.within = within
211
212 - def __str__(self):
213 return "%s %r could not be located in %s"%( 214 self.what, self.lookedFor, self.within)
215 216
217 -class EmptyData(Error):
218 """is raised within certain protocols to signify a request was successful 219 but yielded no data. 220 """
221 222
223 -class RDNotFound(NotFoundError):
224 """is raised when an RD cannot be located. 225 """
226 - def __init__(self, rdId, hint=None):
227 NotFoundError.__init__(self, rdId, hint=hint, what="Resource descriptor", 228 within="file system") 229 self.args = [rdId, hint]
230 231
232 -class ExecutiveAction(Exception):
233 """is a base class for exceptions that are supposed to break out of 234 deep things and trigger actions higher up. 235 """
236 237
238 -class SkipThis(ExecutiveAction):
239 """is caught in rsc.makeData. You can raise this at any place during 240 source processing to skip the rest of this source but the go on. 241 242 You should pass something descriptive as message so upstream can 243 potentially report something is skipped and why. 244 245 Note: in a rowmaker, you probably usually want to raise IgnoreThisRow 246 instead; it's rare that you want to ignore the rest of a source just 247 because you don't like a row. 248 """
249 250 251 try: 252 from pyparsing import ( #noflake: exported name 253 ParseBaseException as ParseException) 254 except ImportError: 255 pass 256