@@ -267,6 +267,53 @@ re-raise the exception::
267267 NameError: HiThere
268268
269269
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+
270317.. _tut-userexceptions :
271318
272319User-defined Exceptions
0 commit comments