@@ -869,8 +869,10 @@ impl dyn Error + Send + Sync {
869869/// Error: SuperError is here!: SuperErrorSideKick is here!
870870/// ```
871871///
872+ /// ## Output consistency
873+ ///
872874/// Report prints the same output via `Display` and `Debug`, so it works well with
873- /// [`unwrap`]/[`expect`]:
875+ /// [`Result:: unwrap`]/[`Result:: expect`] which print their `Err` variant via `Debug` :
874876///
875877/// ```should_panic
876878/// #![feature(error_reporter)]
@@ -912,6 +914,104 @@ impl dyn Error + Send + Sync {
912914/// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
913915/// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
914916/// ```
917+ // /// TODO: Report doesn't yet support return from `main` gracefully, fix in followup (yaahc)
918+ // /// ## Return from `main`
919+ // ///
920+ // /// `Report` also implements `From` for all types that implement [`Error`], this when combined with
921+ // /// the `Debug` output means `Report` is an ideal starting place for formatting errors returned
922+ // /// from `main`.
923+ // ///
924+ // /// ```
925+ // /// #![feature(error_reporter)]
926+ // /// use std::error::Report;
927+ // /// # use std::error::Error;
928+ // /// # use std::fmt;
929+ // /// # #[derive(Debug)]
930+ // /// # struct SuperError {
931+ // /// # source: SuperErrorSideKick,
932+ // /// # }
933+ // /// # impl fmt::Display for SuperError {
934+ // /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
935+ // /// # write!(f, "SuperError is here!")
936+ // /// # }
937+ // /// # }
938+ // /// # impl Error for SuperError {
939+ // /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
940+ // /// # Some(&self.source)
941+ // /// # }
942+ // /// # }
943+ // /// # #[derive(Debug)]
944+ // /// # struct SuperErrorSideKick;
945+ // /// # impl fmt::Display for SuperErrorSideKick {
946+ // /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947+ // /// # write!(f, "SuperErrorSideKick is here!")
948+ // /// # }
949+ // /// # }
950+ // /// # impl Error for SuperErrorSideKick {}
951+ // /// # fn get_super_error() -> Result<(), SuperError> {
952+ // /// # Err(SuperError { source: SuperErrorSideKick })
953+ // /// # }
954+ // ///
955+ // /// fn main() -> Result<(), Report> {
956+ // /// get_super_error()?;
957+ // /// }
958+ // /// ```
959+ // ///
960+ // /// This example produces the following output:
961+ // ///
962+ // /// ```console
963+ // /// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
964+ // /// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
965+ // /// ```
966+ // ///
967+ // /// **Note**: `Report`s constructed via `?` and `From` will be configured to use the single line
968+ // /// output format, if you want to make sure your `Report`s are pretty printed and include backtrace
969+ // /// you will need to manually convert and enable those flags.
970+ // ///
971+ // /// ```
972+ // /// #![feature(error_reporter)]
973+ // /// use std::error::Report;
974+ // /// # use std::error::Error;
975+ // /// # use std::fmt;
976+ // /// # #[derive(Debug)]
977+ // /// # struct SuperError {
978+ // /// # source: SuperErrorSideKick,
979+ // /// # }
980+ // /// # impl fmt::Display for SuperError {
981+ // /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
982+ // /// # write!(f, "SuperError is here!")
983+ // /// # }
984+ // /// # }
985+ // /// # impl Error for SuperError {
986+ // /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
987+ // /// # Some(&self.source)
988+ // /// # }
989+ // /// # }
990+ // /// # #[derive(Debug)]
991+ // /// # struct SuperErrorSideKick;
992+ // /// # impl fmt::Display for SuperErrorSideKick {
993+ // /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
994+ // /// # write!(f, "SuperErrorSideKick is here!")
995+ // /// # }
996+ // /// # }
997+ // /// # impl Error for SuperErrorSideKick {}
998+ // /// # fn get_super_error() -> Result<(), SuperError> {
999+ // /// # Err(SuperError { source: SuperErrorSideKick })
1000+ // /// # }
1001+ // ///
1002+ // /// fn main() -> Result<(), Report> {
1003+ // /// get_super_error()
1004+ // /// .map_err(Report::new)
1005+ // /// .map_err(|r| r.pretty(true).show_backtrace(true))?;
1006+ // /// }
1007+ // /// ```
1008+ // ///
1009+ // /// This example produces the following output:
1010+ // ///
1011+ // /// ```console
1012+ // /// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
1013+ // /// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1014+ // /// ```
9151015#[ unstable( feature = "error_reporter" , issue = "90172" ) ]
9161016pub struct Report < E > {
9171017 /// The error being reported.
@@ -977,6 +1077,68 @@ where
9771077 /// Caused by:
9781078 /// SuperErrorSideKick is here!
9791079 /// ```
1080+ ///
1081+ /// When there are multiple source errors the causes will be numbered in order of iteration
1082+ /// starting from the outermost error.
1083+ ///
1084+ /// ```rust
1085+ /// #![feature(error_reporter)]
1086+ /// use std::error::Report;
1087+ /// # use std::error::Error;
1088+ /// # use std::fmt;
1089+ /// # #[derive(Debug)]
1090+ /// # struct SuperError {
1091+ /// # source: SuperErrorSideKick,
1092+ /// # }
1093+ /// # impl fmt::Display for SuperError {
1094+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1095+ /// # write!(f, "SuperError is here!")
1096+ /// # }
1097+ /// # }
1098+ /// # impl Error for SuperError {
1099+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1100+ /// # Some(&self.source)
1101+ /// # }
1102+ /// # }
1103+ /// # #[derive(Debug)]
1104+ /// # struct SuperErrorSideKick {
1105+ /// # source: SuperErrorSideKickSideKick,
1106+ /// # }
1107+ /// # impl fmt::Display for SuperErrorSideKick {
1108+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1109+ /// # write!(f, "SuperErrorSideKick is here!")
1110+ /// # }
1111+ /// # }
1112+ /// # impl Error for SuperErrorSideKick {
1113+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1114+ /// # Some(&self.source)
1115+ /// # }
1116+ /// # }
1117+ /// # #[derive(Debug)]
1118+ /// # struct SuperErrorSideKickSideKick;
1119+ /// # impl fmt::Display for SuperErrorSideKickSideKick {
1120+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1121+ /// # write!(f, "SuperErrorSideKickSideKick is here!")
1122+ /// # }
1123+ /// # }
1124+ /// # impl Error for SuperErrorSideKickSideKick { }
1125+ ///
1126+ /// let source = SuperErrorSideKickSideKick;
1127+ /// let source = SuperErrorSideKick { source };
1128+ /// let error = SuperError { source };
1129+ /// let report = Report::new(error).pretty(true);
1130+ /// eprintln!("Error: {:?}", report);
1131+ /// ```
1132+ ///
1133+ /// This example produces the following output:
1134+ ///
1135+ /// ```console
1136+ /// Error: SuperError is here!
1137+ ///
1138+ /// Caused by:
1139+ /// 0: SuperErrorSideKick is here!
1140+ /// 1: SuperErrorSideKickSideKick is here!
1141+ /// ```
9801142 #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
9811143 pub fn pretty ( mut self , pretty : bool ) -> Self {
9821144 self . pretty = pretty;
@@ -987,38 +1149,40 @@ where
9871149 ///
9881150 /// # Examples
9891151 ///
1152+ /// **Note**: Report will search for the first `Backtrace` it can find starting from the
1153+ /// outermost error. In this example it will display the backtrace from the second error in the
1154+ /// chain, `SuperErrorSideKick`.
1155+ ///
9901156 /// ```rust
9911157 /// #![feature(error_reporter)]
9921158 /// #![feature(backtrace)]
993- /// use std::error::{Error, Report};
1159+ /// # use std::error::Error;
1160+ /// # use std::fmt;
1161+ /// use std::error::Report;
9941162 /// use std::backtrace::Backtrace;
995- /// use std::fmt;
996- ///
997- /// #[derive(Debug)]
998- /// struct SuperError {
999- /// source: SuperErrorSideKick,
1000- /// }
1001- ///
1002- /// impl fmt::Display for SuperError {
1003- /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1004- /// write!(f, "SuperError is here!")
1005- /// }
1006- /// }
1007- ///
1008- /// impl Error for SuperError {
1009- /// fn source(&self) -> Option<&(dyn Error + 'static)> {
1010- /// Some(&self.source)
1011- /// }
1012- /// }
10131163 ///
1164+ /// # #[derive(Debug)]
1165+ /// # struct SuperError {
1166+ /// # source: SuperErrorSideKick,
1167+ /// # }
1168+ /// # impl fmt::Display for SuperError {
1169+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1170+ /// # write!(f, "SuperError is here!")
1171+ /// # }
1172+ /// # }
1173+ /// # impl Error for SuperError {
1174+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1175+ /// # Some(&self.source)
1176+ /// # }
1177+ /// # }
10141178 /// #[derive(Debug)]
10151179 /// struct SuperErrorSideKick {
10161180 /// backtrace: Backtrace,
10171181 /// }
10181182 ///
1019- /// impl fmt::Display for SuperErrorSideKick {
1020- /// fn fmt(&self, f: &mut fmt::Formatter<'_> ) -> fmt::Result {
1021- /// write!(f, " SuperErrorSideKick is here!")
1183+ /// impl SuperErrorSideKick {
1184+ /// fn new( ) -> SuperErrorSideKick {
1185+ /// SuperErrorSideKick { backtrace: Backtrace::force_capture() }
10221186 /// }
10231187 /// }
10241188 ///
@@ -1028,7 +1192,14 @@ where
10281192 /// }
10291193 /// }
10301194 ///
1031- /// let source = SuperErrorSideKick { backtrace: Backtrace::force_capture() };
1195+ /// // The rest of the example is unchanged ...
1196+ /// # impl fmt::Display for SuperErrorSideKick {
1197+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1198+ /// # write!(f, "SuperErrorSideKick is here!")
1199+ /// # }
1200+ /// # }
1201+ ///
1202+ /// let source = SuperErrorSideKick::new();
10321203 /// let error = SuperError { source };
10331204 /// let report = Report::new(error).pretty(true).show_backtrace(true);
10341205 /// eprintln!("Error: {:?}", report);
@@ -1043,17 +1214,18 @@ where
10431214 /// SuperErrorSideKick is here!
10441215 ///
10451216 /// Stack backtrace:
1046- /// 0: rust_out::main::_doctest_main_src_error_rs_943_0
1047- /// 1: rust_out::main
1048- /// 2: core::ops::function::FnOnce::call_once
1049- /// 3: std::sys_common::backtrace::__rust_begin_short_backtrace
1050- /// 4: std::rt::lang_start::{{closure}}
1051- /// 5: std::panicking::try
1052- /// 6: std::rt::lang_start_internal
1053- /// 7: std::rt::lang_start
1054- /// 8: main
1055- /// 9: __libc_start_main
1056- /// 10: _start
1217+ /// 0: rust_out::main::_doctest_main_src_error_rs_1158_0::SuperErrorSideKick::new
1218+ /// 1: rust_out::main::_doctest_main_src_error_rs_1158_0
1219+ /// 2: rust_out::main
1220+ /// 3: core::ops::function::FnOnce::call_once
1221+ /// 4: std::sys_common::backtrace::__rust_begin_short_backtrace
1222+ /// 5: std::rt::lang_start::{{closure}}
1223+ /// 6: std::panicking::try
1224+ /// 7: std::rt::lang_start_internal
1225+ /// 8: std::rt::lang_start
1226+ /// 9: main
1227+ /// 10: __libc_start_main
1228+ /// 11: _start
10571229 /// ```
10581230 #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
10591231 pub fn show_backtrace ( mut self , show_backtrace : bool ) -> Self {
0 commit comments