-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
try_trait_v2
changed the location of the From::from
caller so the stack trace is different.
#87401
Comments
As per #84277 (comment), applying |
So, if I understand you correctly, then what your code is trying to achieve is to create a stacktrace of all invocations of To my knowledge, this is tracked as "error return traces" here: rust-lang/project-error-handling#9 |
I am seeing this same problem using the |
Yes, and we actually achieved it in a different way. As I can see the RFC mentioned in rust-lang/project-error-handling#9 is not merged so it has no guarantee to be implemented. I think this issue can be considered as broken backward compatibility because our use case worked fine before the |
@artemii235 I want to do a very similar thing to your We considered if we could do it by just patching the std library to add In your case, it looks like |
Can somebody describe to me what the original code was trying to do? Was it to dynamically reconstruct a stack trace around the |
That is correct, to the best of my knowledge. |
@nikomatsakis exactly. The main goal is to track sequentially the places where one error |
I think this is the correct solution going forward that people should reach for when implementing error types that utilize track caller. As Mara mentioned in #88302 (comment) we don't consider track_caller results to be part of our stable API surface, similar to @BGR360 if you plan on publishing a crate for this lmk, otherwise I'll add this to the todo list for the error handling project group. |
@yaahc I'm still pretty new to Rust so I don't really feel qualified to author a general purpose crate for this, nor do I really trust myself to maintain it for the community 😁 . I would be happy to help contribute to the development of a crate, though, and/or to participate in discussion around this topic. What work would you be adding to the project-error-handling todo list for this? The creation of a new crate? Or some sort of new std library feature? |
The former, creating a new crate. If you're interested in working on it we'd be happy to help design/review/maintain it. If you want I'd recommend creating a topic for continuing the conversation about it in https://rust-lang.zulipchat.com/#narrow/stream/257204-project-error-handling. |
@yaahc Custom result type will work great for a new project, but we already have a lot of code relying on how Also, we like a lot that we stick with a standard Result. If we extract some of our code to the crate that other people will use they won't need to import the custom result to pattern match over it. Imagine that you depend on crates, each of which has its own result, you will have a lot of the following: match crate_a_fn {
CrateAResult::Ok(...) => do something,
CrateAResult::Err(...) => do something else,
}
match crate_b_fn {
CrateBResult::Ok(...) => do something,
CrateBResult::Err(...) => do something else,
}
... I don't like how it looks 🙂 (my personal taste, though). With a custom result, we also need a lot of boilerplate: implement all the methods from std (unwrap, map, and others), traits (e.g. TryFuture), etc. As per serde performance loss - is there a way to conditionally enable |
We could add a cfg the same way we did for disabling allocation APIs recently but this would require rebuilding std and is nightly only afaik. @BGR360 has been doing some experimenting with specialization in https://rust-lang.zulipchat.com/#narrow/stream/257204-project-error-handling/topic/track_caller.20error.20crate that looks promising, so we may be able to let error types opt in to The more we've looked into this though the less convinced I am that we should default to not including |
Yet another example of carrying a (string) trace with |
This issue bit me hard updating my Rust version. I use a very minimal approach; all I care about is the exact spot in my code that broke normal flow. Errors that I expect get handled normally without So, I would like to make an argument in favor of
The performance implication of certain core features (like checked indexes) should almost always be left to the developer using said features. The performance implication of It should not be encouraged of users to completely discard core's Edit: So, I gave this more thought and figured out an alternative. A trait can be used to still provide an almost ergonomic alternative. pub trait TrackError<T, E> {
fn track_error(self) -> Result<T, (E, Location)>;
}
impl<T, E> TrackError<T, E> for Result<T, E> where MyError: From<(E, Location)> {
#[track_caller]
fn track_error(self) -> Result<T, (E, Location)> {
match self {
Ok(value) => Ok(value),
Err(error) => Err((error, Location::caller()),
}
}
} Just wrote this off the top of my head, but having it or similar should let a caller do something like: fn some_failable() -> Result<(), MyError> {
let _stuff = do_failable()
.track_error()?;
Ok(())
} |
I've opened #91752 to attempt to resolve the current discussion. |
Readd track_caller to Result::from_residual This is a followup on rust-lang#87401 in and an attempt to move the issue towards resolution. As part of the overhaul of the Try trait we removed the ability for errors to grab location information during propagation via `?` with the builtin `std::result::Result`. The previously linked issue has a fair bit of discussion into the reasons for and against the usage of `#[track_caller]` on the `FromResidual` impl on `Result` that I will do my best to summarize. --- ### For - rust-lang#87401 (comment): Difficulties with using non `std::result::Result` like types - rust-lang#87401 (comment): Inconsistency with functionality provided for recoverable (Result) and non-recoverable errors (panic), where panic provides a location and Result does not, pushing some users towards using panic ### Against - rust-lang#84277 (comment): concern that this will bloat callers that never use this data --- Personally, I want to quantify the performance / bloat impact of re-adding this attribute, and fully evaluate the pros and cons before deciding if I need to switch `eyre` to have a custom `Result` type, which would also mean I need `try_trait_v2` to be stabilized, cc `@scottmcm.` If the performance impact is minor enough in the general case I think I would prefer that the default `Result` type has the ability to track location information for consistency with `panic` error reporting, and leave it to applications that need particularly high performance to handle the micro optimizations of introducing their own efficient custom Result type or matching manually. Alternatively, I wonder if the performance penalty on code that doesn't use the location information on `FromResidual` could be mitigated via new optimizations.
Can this be closed now? |
I'm going to close this since we added back track_caller in #91752; feel free to re-open if you're still running into issues. |
Initial report #84277 (comment)
We have a problem in our project related to the new question mark desugaring. We use the
track_caller
feature inFrom::from
implementation of the error types to collect stack traces with generics and auto and negative impl traits magic implemented by @sergeyboyko0791 (https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2.1/mm2src/common/mm_error/mm_error.rs).After updating to the latest nightly toolchain this stack trace collection started to work differently. I've created a small project for the demo: https://github.com/artemii235/questionmark_track_caller_try_trait_v2
cargo +nightly-2021-05-17 run
outputsLocation { file: "src/main.rs", line: 18, col: 23 }
as we expect.cargo +nightly-2021-07-18 run
outputsLocation { file: "/rustc/c7331d65bdbab1187f5a9b8f5b918248678ebdb9/library/core/src/result.rs", line: 1897, col: 27 }
- thefrom_residual
implementation that is now used for?
desugaring.Is there a way to make the track caller work the same way as it was before? Maybe we can use some workaround in our code?
Thanks in advance for any help!
The text was updated successfully, but these errors were encountered: