Description
Proposal
Problem statement
This is a follow up of the problems documented in https://blog.rust-lang.org/inside-rust/2021/07/01/What-the-error-handling-project-group-is-working-towards.html#1-error-trait--panic-runtime-integration
Motivation, use-cases
Right now the standard library includes multiple interfaces to "promote" an error from an anticipated runtime failure mode to a panic, unwrap
and expect
. These interfaces are currently lossy, since they Debug
format the error and discard the Error
trait interface which is meant to provide structured access to contextual pieces of an error for the purpose of reporting. This PR seeks to allow panic handlers to access the richer Error
trait interface when reporting panics that have a runtime error as their source.
Solution sketches
At a minimum I believe we should add an fn source
to PanicInfo
:
impl PanicInfo<'_> {
pub fn source(&self) -> Option<&(dyn Error + 'static)>;
}
Then, we will need to add interfaces for constructing panics with an additional source error. As a starting point the initial impl PR (linked below) adds the following method
pub const fn panic_source(msg: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> !;
I don't have strong opinions about exactly what this API should look like, or what the name of the method should be.
- I've also considered naming it
panic_with_source
. - I've considered modifications to the
panic!
macropanic!(source = &my_source, "my panic message");
I'm sure there are other approaches as well, very open to suggestions for the best way to structure this.
Finally I think we will need to find some way to integrate these APIs with Result
, either so that unwrap
and expect
will use them internally (not currently possible without making a breaking change or adding new language features) or so that users are steered towards an alternative method when their E
type implements the Error
trait (the problem here is that there's not a good name to use, given that unwrap_err
already exists and means something else1). This is something of an unsolved problem
The best solutions I can think of atm are either (A) to somehow magically solve all the issues with specialization or (B) to change the meaning of unwrap
and expect
across an edition boundary by introducing something like edition dependent function aliases.
The idea with option (B) is:
- rename
unwrap
tounwrap_ok
to matchunwrap_err
, they both requireE: Debug
still - do the same for
expect
toexpect_ok
- introduce new versions of these that require
E: Error
, potentially namedunwrap_source
/expect_source
. - Change
unwrap
andexpect
into edition dependent function aliases where in editions 2021 and earlier they resolve tounwrap_ok
/expect_ok
and in editions 2024 and beyond they resolve tounwrap_source
/expect_source
.
Extremely interested in other ideas, but this is the best I could come up with.
Links and related work
- Initial Impl: Error in panic rust#103169
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.
Footnotes
-
Previous discussion about alternative names: https://rust-lang.zulipchat.com/#narrow/stream/257204-project-error-handling/topic/naming.20bikeshed.20for.20.60expect.60.20with.20Error.20trait ↩