##// END OF EJS Templates
cleanup stale, unused exceptions in parallel.error...
MinRK -
Show More
@@ -1,53 +1,53 b''
1 1 # encoding: utf-8
2 2 """
3 3 Global exception classes for IPython.core.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Min Ragan-Kelley
10 10
11 11 Notes
12 12 -----
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2011 The IPython Development Team
16 # Copyright (C) 2008 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Exception classes
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class IPythonCoreError(Exception):
31 31 pass
32 32
33 33
34 34 class TryNext(IPythonCoreError):
35 35 """Try next hook exception.
36 36
37 37 Raise this in your hook function to indicate that the next hook handler
38 38 should be used to handle the operation.
39 39 """
40 40
41 41 class UsageError(IPythonCoreError):
42 42 """Error in magic function arguments, etc.
43 43
44 44 Something that probably won't warrant a full traceback, but should
45 45 nevertheless interrupt a macro / batch file.
46 46 """
47 47
48 48 class StdinNotImplementedError(IPythonCoreError, NotImplementedError):
49 49 """raw_input was requested in a context where it is not supported
50 50
51 51 For use in IPython kernels, where only some frontends may support
52 52 stdin requests.
53 53 """
@@ -1,354 +1,248 b''
1 1 # encoding: utf-8
2 2
3 3 """Classes and functions for kernel related errors and exceptions.
4 4
5 5 Inheritance diagram:
6 6
7 7 .. inheritance-diagram:: IPython.parallel.error
8 8 :parts: 3
9 9
10 10 Authors:
11 11
12 12 * Brian Granger
13 13 * Min RK
14 14 """
15 15 from __future__ import print_function
16 16
17 17 import sys
18 18 import traceback
19 19
20 20 __docformat__ = "restructuredtext en"
21 21
22 22 # Tell nose to skip this module
23 23 __test__ = {}
24 24
25 25 #-------------------------------------------------------------------------------
26 26 # Copyright (C) 2008-2011 The IPython Development Team
27 27 #
28 28 # Distributed under the terms of the BSD License. The full license is in
29 29 # the file COPYING, distributed as part of this software.
30 30 #-------------------------------------------------------------------------------
31 31
32 32 #-------------------------------------------------------------------------------
33 33 # Error classes
34 34 #-------------------------------------------------------------------------------
35 35 class IPythonError(Exception):
36 36 """Base exception that all of our exceptions inherit from.
37 37
38 38 This can be raised by code that doesn't have any more specific
39 39 information."""
40 40
41 41 pass
42 42
43 # Exceptions associated with the controller objects
44 class ControllerError(IPythonError): pass
45
46 class ControllerCreationError(ControllerError): pass
47
48
49 # Exceptions associated with the Engines
50 class EngineError(IPythonError): pass
51
52 class EngineCreationError(EngineError): pass
53
54 43 class KernelError(IPythonError):
55 44 pass
56 45
57 class NotDefined(KernelError):
58 def __init__(self, name):
59 self.name = name
60 self.args = (name,)
61
62 def __repr__(self):
63 return '<NotDefined: %s>' % self.name
64
65 __str__ = __repr__
66
67
68 class QueueCleared(KernelError):
69 pass
70
71
72 class IdInUse(KernelError):
73 pass
74
75
76 class ProtocolError(KernelError):
77 pass
78
79
80 class ConnectionError(KernelError):
81 pass
82
83
84 class InvalidEngineID(KernelError):
85 pass
86 46
87 47
88 48 class NoEnginesRegistered(KernelError):
89 49 pass
90 50
91 51
92 class InvalidClientID(KernelError):
93 pass
94
95
96 class InvalidDeferredID(KernelError):
97 pass
98
99
100 class SerializationError(KernelError):
101 pass
102
103
104 class MessageSizeError(KernelError):
105 pass
106
107
108 class PBMessageSizeError(MessageSizeError):
109 pass
110
111
112 class ResultNotCompleted(KernelError):
113 pass
114
115
116 class ResultAlreadyRetrieved(KernelError):
117 pass
118
119 class ClientError(KernelError):
120 pass
121
122
123 52 class TaskAborted(KernelError):
124 53 pass
125 54
126 55
127 class TaskTimeout(KernelError):
128 pass
129
130
131 class NotAPendingResult(KernelError):
132 pass
133
134
135 class UnpickleableException(KernelError):
136 pass
137
138
139 class AbortedPendingDeferredError(KernelError):
140 pass
141
142
143 class InvalidProperty(KernelError):
144 pass
145
146
147 class MissingBlockArgument(KernelError):
148 pass
149
150
151 class StopLocalExecution(KernelError):
152 pass
153
154
155 class SecurityError(KernelError):
156 pass
157
158
159 class FileTimeoutError(KernelError):
160 pass
161
162 56 class TimeoutError(KernelError):
163 57 pass
164 58
165 59 class UnmetDependency(KernelError):
166 60 pass
167 61
168 62 class ImpossibleDependency(UnmetDependency):
169 63 pass
170 64
171 65 class DependencyTimeout(ImpossibleDependency):
172 66 pass
173 67
174 68 class InvalidDependency(ImpossibleDependency):
175 69 pass
176 70
177 71 class RemoteError(KernelError):
178 72 """Error raised elsewhere"""
179 73 ename=None
180 74 evalue=None
181 75 traceback=None
182 76 engine_info=None
183 77
184 78 def __init__(self, ename, evalue, traceback, engine_info=None):
185 79 self.ename=ename
186 80 self.evalue=evalue
187 81 self.traceback=traceback
188 82 self.engine_info=engine_info or {}
189 83 self.args=(ename, evalue)
190 84
191 85 def __repr__(self):
192 86 engineid = self.engine_info.get('engine_id', ' ')
193 87 return "<Remote[%s]:%s(%s)>"%(engineid, self.ename, self.evalue)
194 88
195 89 def __str__(self):
196 90 return "%s(%s)" % (self.ename, self.evalue)
197 91
198 92 def render_traceback(self):
199 93 """render traceback to a list of lines"""
200 94 return (self.traceback or "No traceback available").splitlines()
201 95
202 96 def _render_traceback_(self):
203 97 """Special method for custom tracebacks within IPython.
204 98
205 99 This will be called by IPython instead of displaying the local traceback.
206 100
207 101 It should return a traceback rendered as a list of lines.
208 102 """
209 103 return self.render_traceback()
210 104
211 105 def print_traceback(self, excid=None):
212 106 """print my traceback"""
213 107 print('\n'.join(self.render_traceback()))
214 108
215 109
216 110
217 111
218 112 class TaskRejectError(KernelError):
219 113 """Exception to raise when a task should be rejected by an engine.
220 114
221 115 This exception can be used to allow a task running on an engine to test
222 116 if the engine (or the user's namespace on the engine) has the needed
223 117 task dependencies. If not, the task should raise this exception. For
224 118 the task to be retried on another engine, the task should be created
225 119 with the `retries` argument > 1.
226 120
227 121 The advantage of this approach over our older properties system is that
228 122 tasks have full access to the user's namespace on the engines and the
229 123 properties don't have to be managed or tested by the controller.
230 124 """
231 125
232 126
233 127 class CompositeError(RemoteError):
234 128 """Error for representing possibly multiple errors on engines"""
235 129 tb_limit = 4 # limit on how many tracebacks to draw
236 130
237 131 def __init__(self, message, elist):
238 132 Exception.__init__(self, *(message, elist))
239 133 # Don't use pack_exception because it will conflict with the .message
240 134 # attribute that is being deprecated in 2.6 and beyond.
241 135 self.msg = message
242 136 self.elist = elist
243 137 self.args = [ e[0] for e in elist ]
244 138
245 139 def _get_engine_str(self, ei):
246 140 if not ei:
247 141 return '[Engine Exception]'
248 142 else:
249 143 return '[%s:%s]: ' % (ei['engine_id'], ei['method'])
250 144
251 145 def _get_traceback(self, ev):
252 146 try:
253 147 tb = ev._ipython_traceback_text
254 148 except AttributeError:
255 149 return 'No traceback available'
256 150 else:
257 151 return tb
258 152
259 153 def __str__(self):
260 154 s = str(self.msg)
261 155 for en, ev, etb, ei in self.elist[:self.tb_limit]:
262 156 engine_str = self._get_engine_str(ei)
263 157 s = s + '\n' + engine_str + en + ': ' + str(ev)
264 158 if len(self.elist) > self.tb_limit:
265 159 s = s + '\n.... %i more exceptions ...' % (len(self.elist) - self.tb_limit)
266 160 return s
267 161
268 162 def __repr__(self):
269 163 return "CompositeError(%i)" % len(self.elist)
270 164
271 165 def render_traceback(self, excid=None):
272 166 """render one or all of my tracebacks to a list of lines"""
273 167 lines = []
274 168 if excid is None:
275 169 for (en,ev,etb,ei) in self.elist[:self.tb_limit]:
276 170 lines.append(self._get_engine_str(ei))
277 171 lines.extend((etb or 'No traceback available').splitlines())
278 172 lines.append('')
279 173 if len(self.elist) > self.tb_limit:
280 174 lines.append(
281 175 '... %i more exceptions ...' % (len(self.elist) - self.tb_limit)
282 176 )
283 177 else:
284 178 try:
285 179 en,ev,etb,ei = self.elist[excid]
286 180 except:
287 181 raise IndexError("an exception with index %i does not exist"%excid)
288 182 else:
289 183 lines.append(self._get_engine_str(ei))
290 184 lines.extend((etb or 'No traceback available').splitlines())
291 185
292 186 return lines
293 187
294 188 def print_traceback(self, excid=None):
295 189 print('\n'.join(self.render_traceback(excid)))
296 190
297 191 def raise_exception(self, excid=0):
298 192 try:
299 193 en,ev,etb,ei = self.elist[excid]
300 194 except:
301 195 raise IndexError("an exception with index %i does not exist"%excid)
302 196 else:
303 197 raise RemoteError(en, ev, etb, ei)
304 198
305 199
306 200 def collect_exceptions(rdict_or_list, method='unspecified'):
307 201 """check a result dict for errors, and raise CompositeError if any exist.
308 202 Passthrough otherwise."""
309 203 elist = []
310 204 if isinstance(rdict_or_list, dict):
311 205 rlist = rdict_or_list.values()
312 206 else:
313 207 rlist = rdict_or_list
314 208 for r in rlist:
315 209 if isinstance(r, RemoteError):
316 210 en, ev, etb, ei = r.ename, r.evalue, r.traceback, r.engine_info
317 211 # Sometimes we could have CompositeError in our list. Just take
318 212 # the errors out of them and put them in our new list. This
319 213 # has the effect of flattening lists of CompositeErrors into one
320 214 # CompositeError
321 215 if en=='CompositeError':
322 216 for e in ev.elist:
323 217 elist.append(e)
324 218 else:
325 219 elist.append((en, ev, etb, ei))
326 220 if len(elist)==0:
327 221 return rdict_or_list
328 222 else:
329 223 msg = "one or more exceptions from call to method: %s" % (method)
330 224 # This silliness is needed so the debugger has access to the exception
331 225 # instance (e in this case)
332 226 try:
333 227 raise CompositeError(msg, elist)
334 228 except CompositeError as e:
335 229 raise e
336 230
337 231 def wrap_exception(engine_info={}):
338 232 etype, evalue, tb = sys.exc_info()
339 233 stb = traceback.format_exception(etype, evalue, tb)
340 234 exc_content = {
341 235 'status' : 'error',
342 236 'traceback' : stb,
343 237 'ename' : unicode(etype.__name__),
344 238 'evalue' : unicode(evalue),
345 239 'engine_info' : engine_info
346 240 }
347 241 return exc_content
348 242
349 243 def unwrap_exception(content):
350 244 err = RemoteError(content['ename'], content['evalue'],
351 245 ''.join(content['traceback']),
352 246 content.get('engine_info', {}))
353 247 return err
354 248
General Comments 0
You need to be logged in to leave comments. Login now