OLD | NEW |
---|---|
1 # Copyright 2013 The LUCI Authors. All rights reserved. | 1 # Copyright 2013 The LUCI Authors. All rights reserved. |
2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
4 | 4 |
5 import contextlib | 5 import contextlib |
6 import functools | 6 import functools |
7 import os | 7 import os |
8 import sys | 8 import sys |
9 import traceback | 9 import traceback |
10 import urllib | 10 import urllib |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 self.lines[-1].write(s) | 183 self.lines[-1].write(s) |
184 break | 184 break |
185 self.lines[-1].write(s[:i]) | 185 self.lines[-1].write(s[:i]) |
186 self.lines[-1] = self.lines[-1].getvalue() | 186 self.lines[-1] = self.lines[-1].getvalue() |
187 self.lines.append(StringIO()) | 187 self.lines.append(StringIO()) |
188 s = s[i+1:] | 188 s = s[i+1:] |
189 | 189 |
190 def close(self): | 190 def close(self): |
191 if not isinstance(self.lines[-1], basestring): | 191 if not isinstance(self.lines[-1], basestring): |
192 self.lines[-1] = self.lines[-1].getvalue() | 192 self.lines[-1] = self.lines[-1].getvalue() |
193 | |
194 | |
195 class MultiException(Exception): | |
196 """An exception that aggregates multiple exceptions and summarizes them.""" | |
197 | |
198 def __init__(self): | |
199 self._inner = [] | |
200 | |
201 def append(self, exc): | |
202 assert isinstance(exc, BaseException) | |
203 self._inner.append(exc) | |
204 | |
205 def __nonzero__(self): | |
206 return bool(self._inner) | |
207 | |
208 def __str__(self): | |
209 if len(self._inner) == 0: | |
210 text = 'No exceptions' | |
211 elif len(self._inner) == 1: | |
212 text = str(self._inner[0]) | |
213 else: | |
214 text = str(self._inner[0]) + ', and %d more...' % (len(self._inner)-1) | |
215 return '%s(%s)' % (type(self).__name__, text) | |
216 | |
217 def raise_if_any(self): | |
218 if self: | |
martiniss
2016/09/01 21:59:48
Shouldn't this be "if self._inner"?
dnj
2016/09/07 17:54:58
Done.
| |
219 raise self | |
220 | |
221 @contextlib.contextmanager | |
222 def catch(self): | |
223 try: | |
224 yield | |
225 except Exception as e: | |
martiniss
2016/09/01 21:59:48
Can you make the exception class a required parame
dnj
2016/09/07 17:54:58
Sure.
However, note the only user ("defer_excepti
| |
226 self.append(e) | |
227 | |
228 | |
229 def defer_exceptions_for(gen): | |
230 mexc = MultiException() | |
231 for e in gen: | |
232 try: | |
233 yield e | |
234 except Exception as e: | |
235 exc.append(e) | |
236 mexc.raise_if_any() | |
OLD | NEW |