Skip to content

Commit af8cb3b

Browse files
committed
Chain exceptions while unwinding
1 parent 12e1560 commit af8cb3b

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

py/vm.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,10 +1453,19 @@ unwind_jump:;
14531453
// catch exception and pass to byte code
14541454
code_state->ip = exc_sp->handler;
14551455
mp_obj_t *sp = MP_TAGPTR_PTR(exc_sp->val_sp);
1456+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
1457+
mp_obj_t active_exception = get_active_exception(exc_sp, exc_stack);
1458+
#endif
14561459
// save this exception in the stack so it can be used in a reraise, if needed
14571460
exc_sp->prev_exc = nlr.ret_val;
1461+
mp_obj_t obj = MP_OBJ_FROM_PTR(nlr.ret_val);
1462+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
1463+
if (active_exception != MP_OBJ_NULL) {
1464+
mp_store_attr(obj, MP_QSTR___context__, active_exception);
1465+
}
1466+
#endif
14581467
// push exception object so it can be handled by bytecode
1459-
PUSH(MP_OBJ_FROM_PTR(nlr.ret_val));
1468+
PUSH(obj);
14601469
code_state->sp = sp;
14611470

14621471
#if MICROPY_STACKLESS

tests/basics/exception_chain.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
raise SystemExit
66

77
def print_exc_info(e):
8-
print("exception", type(e), repr(e))
8+
print("exception", type(e), e.args)
99
print("context", type(e.__context__), e.__suppress_context__)
1010
print("cause", type(e.__cause__))
1111

@@ -44,3 +44,11 @@ def print_exc_info(e):
4444
raise RuntimeError() from None
4545
except Exception as e:
4646
print_exc_info(e)
47+
48+
try:
49+
try:
50+
raise RuntimeError()
51+
except Exception as inner:
52+
1/0
53+
except Exception as e:
54+
print_exc_info(e)

tests/circuitpython/traceback_test_chained.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,11 @@ def print_exc_info(e):
5353
raise RuntimeError() from None
5454
except Exception as e:
5555
print_exc_info(e)
56+
57+
try:
58+
try:
59+
raise RuntimeError()
60+
except Exception as inner:
61+
1 / 0
62+
except Exception as e:
63+
print_exc_info(e)

tests/circuitpython/traceback_test_chained.py.exp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,15 @@ Traceback (most recent call last):
4141
RuntimeError:
4242
------------------------------------------------------------------------
4343

44+
------------------------------------------------------------------------
45+
Traceback (most recent call last):
46+
File "circuitpython/traceback_test_chained.py", line 59, in <module>
47+
RuntimeError:
48+
49+
During handling of the above exception, another exception occurred:
50+
51+
Traceback (most recent call last):
52+
File "circuitpython/traceback_test_chained.py", line 61, in <module>
53+
ZeroDivisionError: division by zero
54+
------------------------------------------------------------------------
55+

0 commit comments

Comments
 (0)