Recursively print chained exceptions
This commit is contained in:
parent
f3169246ba
commit
b6f86e1e73
@ -106,7 +106,7 @@ msgstr ""
|
||||
msgid "%q in use"
|
||||
msgstr ""
|
||||
|
||||
#: py/obj.c py/objstr.c py/objstrunicode.c
|
||||
#: py/objstr.c py/objstrunicode.c
|
||||
msgid "%q index out of range"
|
||||
msgstr ""
|
||||
|
||||
@ -171,11 +171,11 @@ msgstr ""
|
||||
msgid "%q must be an int"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
#: py/argcheck.c py/obj.c
|
||||
msgid "%q must be of type %q"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/digitalio/Pull.c
|
||||
#: py/objexcept.c shared-bindings/digitalio/Pull.c
|
||||
msgid "%q must be of type %q or None"
|
||||
msgstr ""
|
||||
|
||||
@ -894,6 +894,10 @@ msgstr ""
|
||||
msgid "Drive mode not used when direction is input."
|
||||
msgstr ""
|
||||
|
||||
#: py/obj.c
|
||||
msgid "During handling of the above exception, another exception occurred:"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/aesio/aes.c
|
||||
msgid "ECB only operates on 16 bytes at a time"
|
||||
msgstr ""
|
||||
@ -2007,6 +2011,10 @@ msgid ""
|
||||
"exit safe mode."
|
||||
msgstr ""
|
||||
|
||||
#: py/obj.c
|
||||
msgid "The above exception was the direct cause of the following exception:"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h
|
||||
msgid "The central button was pressed at start up.\n"
|
||||
msgstr ""
|
||||
@ -3153,7 +3161,7 @@ msgid "index is out of bounds"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c
|
||||
#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c
|
||||
#: ports/espressif/common-hal/pulseio/PulseIn.c
|
||||
#: shared-bindings/bitmaptools/__init__.c
|
||||
msgid "index out of range"
|
||||
msgstr ""
|
||||
@ -3336,10 +3344,6 @@ msgstr ""
|
||||
msgid "invalid syntax for number"
|
||||
msgstr ""
|
||||
|
||||
#: py/objexcept.c
|
||||
msgid "invalid traceback"
|
||||
msgstr ""
|
||||
|
||||
#: py/objtype.c
|
||||
msgid "issubclass() arg 1 must be a class"
|
||||
msgstr ""
|
||||
|
24
py/obj.c
24
py/obj.c
@ -142,9 +142,33 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
|
||||
mp_obj_print_helper(MP_PYTHON_PRINTER, o_in, kind);
|
||||
}
|
||||
|
||||
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);
|
||||
const compressed_string_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;
|
||||
}
|
||||
if (inner && !inner->marked) {
|
||||
inner->marked = true;
|
||||
mp_obj_print_exception_with_limit(print, MP_OBJ_FROM_PTR(inner), limit);
|
||||
inner->marked = false;
|
||||
mp_printf(print, "\n");
|
||||
mp_cprintf(print, msg);
|
||||
mp_printf(print, "\n\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// helper function to print an exception with traceback
|
||||
void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit) {
|
||||
if (mp_obj_is_exception_instance(exc) && stack_ok()) {
|
||||
mp_obj_print_inner_exception(print, exc, limit);
|
||||
|
||||
size_t n, *values;
|
||||
mp_obj_exception_get_traceback(exc, &n, &values);
|
||||
if (n > 0) {
|
||||
|
@ -34,8 +34,11 @@ typedef struct _mp_obj_exception_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_tuple_t *args;
|
||||
mp_obj_traceback_t *traceback;
|
||||
mp_obj_t cause, context;
|
||||
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
|
||||
struct _mp_obj_exception_t *cause, *context;
|
||||
bool suppress_context;
|
||||
bool marked;
|
||||
#endif
|
||||
} mp_obj_exception_t;
|
||||
|
||||
void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
|
||||
|
55
tests/circuitpython/traceback_test_chained.py
Normal file
55
tests/circuitpython/traceback_test_chained.py
Normal file
@ -0,0 +1,55 @@
|
||||
try:
|
||||
Exception().__cause__
|
||||
except AttributeError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
try:
|
||||
import traceback
|
||||
except:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def print_exc_info(e):
|
||||
print("-" * 72)
|
||||
traceback.print_exception(None, e, e.__traceback__)
|
||||
print("-" * 72)
|
||||
print()
|
||||
|
||||
|
||||
try:
|
||||
try:
|
||||
1 / 0
|
||||
except Exception as inner:
|
||||
raise RuntimeError() from inner
|
||||
except Exception as e:
|
||||
print_exc_info(e)
|
||||
print()
|
||||
|
||||
try:
|
||||
try:
|
||||
1 / 0
|
||||
except Exception as inner:
|
||||
raise RuntimeError() from OSError()
|
||||
except Exception as e:
|
||||
print_exc_info(e)
|
||||
print()
|
||||
|
||||
|
||||
try:
|
||||
try:
|
||||
1 / 0
|
||||
except Exception as inner:
|
||||
raise RuntimeError()
|
||||
except Exception as e:
|
||||
print_exc_info(e)
|
||||
print()
|
||||
|
||||
try:
|
||||
try:
|
||||
1 / 0
|
||||
except Exception as inner:
|
||||
raise RuntimeError() from None
|
||||
except Exception as e:
|
||||
print_exc_info(e)
|
43
tests/circuitpython/traceback_test_chained.py.exp
Normal file
43
tests/circuitpython/traceback_test_chained.py.exp
Normal file
@ -0,0 +1,43 @@
|
||||
------------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 23, in <module>
|
||||
ZeroDivisionError: division by zero
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 25, in <module>
|
||||
RuntimeError:
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
OSError:
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 34, in <module>
|
||||
RuntimeError:
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 42, in <module>
|
||||
ZeroDivisionError: division by zero
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 44, in <module>
|
||||
RuntimeError:
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "circuitpython/traceback_test_chained.py", line 53, in <module>
|
||||
RuntimeError:
|
||||
------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user