Fix chaining non-built-in exceptions

This commit is contained in:
Jeff Epler 2024-05-21 16:40:58 -04:00
parent 41eee0d5ea
commit 49cbbd198a
3 changed files with 91 additions and 7 deletions

View file

@ -143,18 +143,28 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_print_helper(MP_PYTHON_PRINTER, o_in, kind);
}
// CIRCUITPY-CHANGE
static mp_obj_t mp_load_attr_or_none(mp_obj_t base, qstr attr) {
mp_obj_t dest[2];
mp_load_method_protected(base, attr, dest, true);
return dest[0] == MP_OBJ_NULL ? mp_const_none : dest[0];
}
// CIRCUITPY-CHANGE
static void mp_obj_print_inner_exception(const mp_print_t *print, mp_obj_t self_in, mp_int_t limit) {
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
mp_obj_exception_t *self = mp_obj_exception_get_native(self_in);
mp_rom_error_text_t msg = MP_ERROR_TEXT("During handling of the above exception, another exception occurred:");
mp_obj_exception_t *inner = NULL;
if (self->cause) {
msg = MP_ERROR_TEXT("The above exception was the direct cause of the following exception:");
inner = self->cause;
} else if (!self->suppress_context) {
inner = self->context;
mp_obj_t inner_obj = mp_const_none;
if (!self->suppress_context) {
inner_obj = mp_load_attr_or_none(self_in, MP_QSTR___context__);
}
if (inner_obj == mp_const_none) {
msg = MP_ERROR_TEXT("The above exception was the direct cause of the following exception:");
inner_obj = mp_load_attr_or_none(self_in, MP_QSTR___cause__);
}
mp_obj_exception_t *inner = mp_obj_is_exception_instance(inner_obj) ?
mp_obj_exception_get_native(inner_obj) : NULL;
if (inner && !inner->marked) {
inner->marked = true;
mp_obj_print_exception_with_limit(print, MP_OBJ_FROM_PTR(inner), limit);

View file

@ -109,7 +109,6 @@ try:
l = inner
raise Exception("outer") from l
except Exception as e:
print(e, e.__cause__, e.__context__)
print_exc_info(e)
print()

View file

@ -74,3 +74,78 @@ ZeroDivisionError: division by zero
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 81, in <module>
Exception: inner
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 83, in <module>
SomeException: outer
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 89, in <module>
Exception: inner
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 92, in <module>
SomeException: outer
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 99, in <module>
RuntimeError: inner
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 101, in <module>
Exception: outer
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 107, in <module>
RuntimeError: inner
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 110, in <module>
Exception: outer
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 117, in <module>
RuntimeError: inner
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 119, in <module>
SomeException: outer
------------------------------------------------------------------------
------------------------------------------------------------------------
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 125, in <module>
RuntimeError: inner
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "circuitpython/traceback_test_chained.py", line 128, in <module>
SomeException: outer
------------------------------------------------------------------------