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
Better ergonomics for exceptions #56
Comments
Are you familiar with C#'s
Some notes compared to
|
+1 for an option to elide stack frames. Here I'll consider how this might behave and show a concrete example. Proposed behavior:
Program specimen is (roughly) https://gist.github.com/nonsleepr/43420a0ce659f1b870544fffb9e5cda4 Original trace (with paths shortened):
Trace with trio frames elided (including async_generator, contextvars, and contextlib dependencies) using MIN_FRAMES_ELIDED=2:
|
notes from @njsmith:
|
From #393 :
|
I've seen some recent developer articles complaining about unintelligible exception traces from RxJava and Kotlin. Granted it presents future obstacles, but traces with elided frames would be a big differentiator for Trio. https://proandroiddev.com/forget-rxjava-kotlin-coroutines-are-all-you-need-part-1-2-4f62ecc4f99b |
@belm0 Oh yeah, it's absolutely a real problem, and we need to find a solution one way or another. The thing about traceback elision that makes me hesitate is, in the long run, we have to find a way to get out of the business of monkeypatching every traceback printer in the world. It's just not maintainable. (See the discussion at the beginning of #611.) And that means that if we want traceback elision to work long-term, we need to come up with a way to move the whole Python ecosystem in that direction. This is doable, and should probably be done: the pytest folks have their own hack for it ( OTOH, keeping the tracebacks simple in the first place is something we can do with relatively small, straightforward changes today. In many cases it's probably simpler than elision (e.g., it's not totally obvious how to write/tune/test the heuristics, and you avoid needing to create/test/document tuning knobs like Let's take a look at a concrete case. I'll use your example from #612 (comment):
User code, this is what we want to see.
This is... a lot of junk, mostly specific to entering trio. I'm not going to squint at it too closely right now, because it's the bottom of the traceback where it's most important to make things readable, plus I think a lot of this clutter will go away if we fix the things below. Maybe not all of it, but it'll be easier to revisit after dealing with the higher priority stuff.
User code; this is what we want to see.
Ick. This is what I was referring to here when I mentioned making the whole nursery Also, when we stop compressing
This is noise... when we catch a user exception in
This line will disappear on 3.7, where
User code, this is what we want to see :-).
We could remove a line here by inlining So to-do list for now, ordered by bang-for-buck:
|
The main cluttered tracebacks problem was fixed by #612, #631, #640, and for all the other complaints at the top of this thread the current plan for fixing them is in #611, so I'm going to close this. There are probably still a few places where we can fine-tune exception tracebacks, but we can open a new issue for that. Or possibly even claim one of the reserved issues if we want to have a single place for people to report little nits as they notice them. |
Our error-reporting story is tolerable at this point (see #49 for some history), but could definitely still be improved. This collects some misc ideas:
@asynccontextmanager
and@async_generator
to reduce extraneous framesError.unwrap
) and out (_task_finished
) of tasks, update a record likeexc.__trio_task_context__
with entries like(len(tb), "exit", task)
, and use them to add context to printed tracebacks. (The need to computelen
is a bit unfortunate though... I guess ideally these should be attributes on the tb objects themselves? But tb objects don't have__dict__
s. Or we could just stash the tb object.)MultiError.filter
needs to be careful to propagate these correctly when propagating tracebacks.MultiError.catch
is OK, but could be better__context__
onMultiError
stry: raise exc except: ...
thing, then they get corrupt tracebacks (we assume that the filter callback doesn't touch the traceback). We could potentially detect new tb frames appearing and fix them up.MultiError
s and use our regularMultiError
printing code. This is good b/c it gives full information, but bad b/c it loses out on IPython's enhanced exception formatting. Better ergonomics for working with MultiErrors #49 has some notes on how this might be possible to get both. (Note that this becomes more of an issue if we do as suggested above and start customizing all exception output and not justMultiError
!) Possibly should chat with the IPython devs about this.The text was updated successfully, but these errors were encountered: