-
Notifications
You must be signed in to change notification settings - Fork 18
Proposal: Reporter inversion #53
Comments
Initial thoughts:
|
@mystor pointed out that if we implemented the lint on format_args it would end up covering the tracing and log macros as well. |
That's fair! After reading your write-up, and pondering about it over lunch, I thought: what if it's as easy as the
Yes, that's right. In the opaque case, I'd be fine with giving out the
That's not my intention. I want application developers to be able to express the format similar to how you would do with formatting most other types, with format flags. There could eventually be a way to provide custom innards of But the stated problem does currently exist. If a crate author follows the advice of not putting the value in
That's certainly an option, and feels like an extension of what I've proposed so far. |
Did you see the snippet I posted about how to potentially prevent downcasting without otherwise altering the chain of sources? I feel like that has the potential to completely solve the second problem you listed as trying to solve and lets us focus the conversation on solving the first problem which I agree 100% is a severe issue and is one of the elements of error reporting I'm most interested in improving. The only problem with the snippet is it would probably need to be a language feature because we couldn't add such an opaque error wrapper type to the standard library without then making it possible for people to downcast to it. |
I tried playing around with your snippet, trying to come up with some generic |
Hmm, I think I see what you're getting at. I'm not able to think of any way to make an opaque type that can reapply itself recursively to it's sources, so I went ahead and opened a thread in #t-lang to try to nerd snipe some other clever people into brainstorming alternative solutions: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/disabling.20downcast.20on.20Error.20types |
what if there was a |
I would like to propose the idea of inverting the way error reporters generally work in Rust. Instead of a reporter iterating all causes of an error to format them, pass in format rules to the top-level error.
The problems I'm trying to solve are:
Problems
Default to most common case
I posit that the most common case that users print errors is for log purposes. I'll use an example of code I've seen over and over:
The current best practices hopes to educate users who have done this to either change the error type they've been returning at this top-ish level tasks, or to remember to wrap the error in a reporter right before printing it.
I suggest that, instead of relying on education, the best practice simply assumes most users won't know about reporters. This change makes it so the common case simply prints all of the error chain to their logs. Specifically, separated by a
:
, not with newlines.Once a user is educated about reporters, they can opt-in to customizing further, such as choosing newlines over colons, or how many down the stack to go, or whatever. When opted into a reporter, the reporter can then tell the
Display
of the error "I only want the top error plz".As prior art, Go's simple way to wrap an error includes displaying it together on the same line, while also being available from
errors.Unwrap
.Opaque errors don't know their context
Some libraries may wish to wrap errors in an opaque way, such that they don't expose the source so that users don't depend on a specific error. This is common in other languages, when it's preferred to not couple the internal details to the error, while still wanting to be to share the error messages to help debugging. hyper is one library with that desire.
Since these opaque errors don't include the wrapped error in
source
, the current reporters cannot access them. But since no context is provided toDisplay
, the opaque error cannot try to mimic the output of the rest of the stack.Solution
The format traits already include a way to inject some context: the
std::fmt::Formatter
. That's how a type can checkf.alternate()
orf.fill()
. Some of those are unused by structs, which we could overload. Or, we could define new ones.I outlined overloading some existing format flags a few years ago. My opinion about some details has changed since then, mostly that I believe the default should be to print everything in a single-line friendly mode, since as I described above, that's what I think the most common case is.
I appreciate that the proposal allows specifying how deep down the stack to print. It also uses
f.alternate()
to determine if it should fit on one line, or use newlines and a stack trace. If we created new flags, we could inject a mode or even "separator" characters, similar tof.fill()
. However, the exact details are a bit of a bikeshed, and what I want most is simply to have the idea of inverting the reporters to be considered.The text was updated successfully, but these errors were encountered: