Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in MultiError.filter: pushing down tracebacks unnecessarily #641

Closed
njsmith opened this issue Sep 2, 2018 · 1 comment
Closed

Bug in MultiError.filter: pushing down tracebacks unnecessarily #641

njsmith opened this issue Sep 2, 2018 · 1 comment

Comments

@njsmith
Copy link
Member

njsmith commented Sep 2, 2018

[Not sure if this is worth fixing given that we're hopefully going to rip out MultiError.filter soon, see #611. But figured I should write it down. If nothing else this is more evidence for how tricky MultiError.filter is...]

I just noticed this playing with python notes-to-self/trivial-err.py, after #640 was merged. We get:

[... some output elided ...]
Details of embedded exception 2:

  trio.MultiError: NameError('Bob',), KeyError()

  Details of embedded exception 1:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 12, in child2
        nursery.start_soon(grandchild2)
      File "/home/njs/trio/trio/_core/_run.py", line 399, in __aexit__
        raise scope_exc
      File "notes-to-self/trivial-err.py", line 18, in grandchild2
        raise NameError("Bob")
    NameError: Bob

  Details of embedded exception 2:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 12, in child2
        nursery.start_soon(grandchild2)
      File "/home/njs/trio/trio/_core/_run.py", line 399, in __aexit__
        raise scope_exc
      File "notes-to-self/trivial-err.py", line 15, in grandchild1
        raise KeyError
    KeyError

Notice how the MultiError at the top has no traceback frames, and the NameError and KeyError inside it have identical child2 and __aexit__ frames.

What should happen here is that the child2 and __aexit__ frames are on the MultiError once, instead of being pushed down onto the individual exceptions.

I added some code to CancelScope._close to see what was going on:

            import traceback
            print("pre-filter")
            if exc is not None:
                traceback.print_exception(type(exc), exc, exc.__traceback__)
            filtered_exc = MultiError.filter(self._exc_filter, exc)
            print("post-filter")
            if filtered_exc is not None:
                traceback.print_exception(type(filtered_exc), filtered_exc, filtered_exc.__traceback__)
            return filtered_exc

and it looks like at some point we have an exception:

trio.MultiError: ValueError(), Cancelled(), <MultiError: Cancelled(), Cancelled(), NameError('Bob',), KeyError()>

and that embedded MultiError with the NameError and KeyError inside it has those two frames on it:

Details of embedded exception 3:

  Traceback (most recent call last):
    File "notes-to-self/trivial-err.py", line 12, in child2
      nursery.start_soon(grandchild2)
    File "/home/njs/trio/trio/_core/_run.py", line 399, in __aexit__
      raise scope_exc
  trio.MultiError: Cancelled(), Cancelled(), NameError('Bob',), KeyError()

[...]

  Details of embedded exception 3:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 18, in grandchild2
        raise NameError("Bob")
    NameError: Bob

  Details of embedded exception 4:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 15, in grandchild1
        raise KeyError
    KeyError

And then MultiError.filter removes the Cancelled exceptions, and somehow in the process it ends up pushing down the tracebacks onto the individual frames:

post-filter
trio.MultiError: ValueError(), <MultiError: NameError('Bob',), KeyError()>

[...]

Details of embedded exception 2:

  trio.MultiError: NameError('Bob',), KeyError()

  Details of embedded exception 1:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 12, in child2
        nursery.start_soon(grandchild2)
      File "/home/njs/trio/trio/_core/_run.py", line 399, in __aexit__
        raise scope_exc
      File "notes-to-self/trivial-err.py", line 18, in grandchild2
        raise NameError("Bob")
    NameError: Bob

  Details of embedded exception 2:

    Traceback (most recent call last):
      File "notes-to-self/trivial-err.py", line 12, in child2
        nursery.start_soon(grandchild2)
      File "/home/njs/trio/trio/_core/_run.py", line 399, in __aexit__
        raise scope_exc
      File "notes-to-self/trivial-err.py", line 15, in grandchild1
        raise KeyError
    KeyError

That's not supposed to happen... we're replacing one MultiError with another, so the traceback frames are supposed to be transferred over.

@Zac-HD
Copy link
Member

Zac-HD commented Nov 3, 2022

Closing this as ExceptionGroup now exists and is an upstream problem.

@Zac-HD Zac-HD closed this as completed Nov 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants