Skip to content

Commit dd443ba

Browse files
committed
Chain exceptions while unwinding
1 parent b6f86e1 commit dd443ba

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
@@ -1456,10 +1456,19 @@ unwind_jump:;
14561456
// catch exception and pass to byte code
14571457
code_state->ip = exc_sp->handler;
14581458
mp_obj_t *sp = MP_TAGPTR_PTR(exc_sp->val_sp);
1459+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
1460+
mp_obj_t active_exception = get_active_exception(exc_sp, exc_stack);
1461+
#endif
14591462
// save this exception in the stack so it can be used in a reraise, if needed
14601463
exc_sp->prev_exc = nlr.ret_val;
1464+
mp_obj_t obj = MP_OBJ_FROM_PTR(nlr.ret_val);
1465+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
1466+
if (active_exception != MP_OBJ_NULL) {
1467+
mp_store_attr(obj, MP_QSTR___context__, active_exception);
1468+
}
1469+
#endif
14611470
// push exception object so it can be handled by bytecode
1462-
PUSH(MP_OBJ_FROM_PTR(nlr.ret_val));
1471+
PUSH(obj);
14631472
code_state->sp = sp;
14641473

14651474
#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)