bt2: don't print previous causes in causes created from bt2._Error
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 2 Dec 2019 17:10:41 +0000 (12:10 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 20 Jan 2020 20:15:24 +0000 (15:15 -0500)
commitb53cd76821d15e3d80780f5d527aa4074ba71256
tree1e95f71125fb0d353552825a01815b141f265732
parent701698c8de3db89105f62ad3008f55db665c2059
bt2: don't print previous causes in causes created from bt2._Error

When an API call from Python fails, we create a bt2._Error that will
take the bt_error from the current thread and assume its ownership.  If
that bt2._Error escapes the Python code and is caught by the Babeltrace
native code, we convert that bt2._Error to a new cause.  We call str()
on the bt2._Error (through bt_py_common_format_exception) to obtain the
text with which to create the new cause.  However, the str() for
bt2._Error textually formats all the existing causes.  As a result, the
text for the new cause includes the string formatting of all the
previous causes.  When the CLI, for example, ends up printing all error
causes successively, it becomes very confusing: the text of one cause
includes the text of previous causes.

What we want, in fact, is not an str() of the bt2._Error, but just a
message that includes the traceback (to know where in the Python code
the cause was created) and the message passed to bt2._Error.__init__.
The traceback is just a goodie: we don't include it for causes created
in C, but since it's easy to obtain in Python it is nice to have.  There
is also the fact the file:line information for causes created in Python
is bogus (which should be fixed at some point), so the traceback fills
in for that for the moment.

This patch changes
restore_current_thread_error_and_append_exception_chain_recursive to
do this for bt2._Error.  For other exceptions, we still call
bt_py_common_format_exception, which ends up calling their __str__.

Here's an example:

    Traceback (most recent call last):
      File "test_simple.py", line 32, in <module>
        graph.run()
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/graph.py", line 188, in run
        utils._handle_func_status(status, 'graph object stopped running')
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/utils.py", line 140, in _handle_func_status
        raise bt2._Error(msg)
    bt2.error._Error: graph object stopped running
    [libbabeltrace2] (/home/smarchi/src/babeltrace/src/lib/graph/graph.c:600)
    Component's "consume" method failed: status=ERROR, comp-addr=0x1f15f50, comp-name="snk", comp-log-level=NONE, comp-class-type=SINK, comp-class-name="DummySink", comp-class-partial-descr="", comp-class-is-frozen=1, comp-input-port-count=1, comp-output-port-count=0
    [snk: sink.DummySink] (/home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h:99)
    Traceback (most recent call last):
      File "test_simple.py", line 26, in _user_consume
        next(self._iter)
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/message_iterator.py", line 58, in __next__
        status, 'unexpected error: cannot advance the message iterator'
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/utils.py", line 140, in _handle_func_status
        raise bt2._Error(msg)
    bt2.error._Error: unexpected error: cannot advance the message iterator
    [libbabeltrace2] (/home/smarchi/src/babeltrace/src/lib/graph/iterator.c:928)
    Component input port message iterator's "next" method failed: iter-addr=0x1ec1980, iter-upstream-comp-name="src", iter-upstream-comp-log-level=NONE, iter-upstream-comp-class-type=SOURCE, iter-upstream-comp-class-name="SourceWithFailingIter", iter-upstream-comp-class-partial-descr="", iter-upstream-port-type=OUTPUT, iter-upstream-port-name="out", status=ERROR
    [src (out): src.SourceWithFailingIter] (/home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h:102)
    Traceback (most recent call last):
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/message_iterator.py", line 201, in _bt_next_from_native
        msg = next(self)
      File "test_simple.py", line 8, in __next__
        raise ValueError('User message iterator is failing')
    ValueError: User message iterator is failing

    [libbabeltrace2] (/home/smarchi/src/babeltrace/src/lib/graph/iterator.c:928)
    Component input port message iterator's "next" method failed: iter-addr=0x1ec1980, iter-upstream-comp-name="src", iter-upstream-comp-log-level=NONE, iter-upstream-comp-class-type=SOURCE, iter-upstream-comp-class-name="SourceWithFailingIter", iter-upstream-comp-class-partial-descr="", iter-upstream-port-type=OUTPUT, iter-upstream-port-name="out", status=ERROR
    [src (out): src.SourceWithFailingIter] (/home/smarchi/src/babeltrace/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h:102)
    Traceback (most recent call last):
      File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/message_iterator.py", line 201, in _bt_next_from_native
        msg = next(self)
      File "test_simple.py", line 8, in __next__
        raise ValueError('User message iterator is failing')
    ValueError: User message iterator is failing

Notice how the "ValueError: User message iterator is failing" cause
seems to appear twice?  The first of them is in fact part of the text of
the "bt2.error._Error: unexpected error: cannot advance the message
iterator" cause.  With this patch applied, the first one of these does
not appear.

Change-Id: I9b3e2e6f78f5ee2ba49a0956f6ef77dbb23dadc4
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2557
Tested-by: jenkins <jenkins@lttng.org>
src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h
src/py-common/py-common.c
src/py-common/py-common.h
This page took 0.025272 seconds and 4 git commands to generate.