@@ -267,6 +267,53 @@ re-raise the exception::
267
267
NameError: HiThere
268
268
269
269
270
+ .. _tut-exception-chaining :
271
+
272
+ Exception Chaining
273
+ ==================
274
+
275
+ The :keyword: `raise ` statement allows an optional :keyword: `from ` which enables
276
+ chaining exceptions by setting the ``__cause__ `` attribute of the raised
277
+ exception. For example::
278
+
279
+ raise RuntimeError from OSError
280
+
281
+ This can be useful when you are transforming exceptions. For example::
282
+
283
+ >>> def func():
284
+ ... raise IOError
285
+ ...
286
+ >>> try:
287
+ ... func()
288
+ ... except IOError as exc:
289
+ ... raise RuntimeError('Failed to open database') from exc
290
+ ...
291
+ Traceback (most recent call last):
292
+ File "<stdin>", line 2, in <module>
293
+ File "<stdin>", line 2, in func
294
+ OSError
295
+ <BLANKLINE>
296
+ The above exception was the direct cause of the following exception:
297
+ <BLANKLINE>
298
+ Traceback (most recent call last):
299
+ File "<stdin>", line 4, in <module>
300
+ RuntimeError
301
+
302
+ The expression following the :keyword: `from ` must be either an exception or
303
+ ``None ``. Exception chaining happens automatically when an exception is raised
304
+ inside an exception handler or :keyword: `finally ` section. Exception chaining
305
+ can be disabled by using ``from None `` idiom:
306
+
307
+ >>> try :
308
+ ... open (' database.sqlite' )
309
+ ... except IOError :
310
+ ... raise RuntimeError from None
311
+ ...
312
+ Traceback (most recent call last):
313
+ File "<stdin>", line 4, in <module>
314
+ RuntimeError
315
+
316
+
270
317
.. _tut-userexceptions :
271
318
272
319
User-defined Exceptions
0 commit comments