Skip to content

Commit 4420cc3

Browse files
committed
Update report output and fix examples
1 parent 1386a15 commit 4420cc3

File tree

2 files changed

+245
-82
lines changed

2 files changed

+245
-82
lines changed

library/std/src/error.rs

+160-35
Original file line numberDiff line numberDiff line change
@@ -808,43 +808,63 @@ impl dyn Error + Send + Sync {
808808
}
809809
}
810810

811-
/// An error reporter that exposes the entire error chain for printing.
812-
/// It also exposes options for formatting the error chain, either entirely on a single line,
813-
/// or in multi-line format with each cause in the error chain on a new line.
811+
/// An error reporter that print's an error and its sources.
812+
///
813+
/// Report also exposes configuration options for formatting the error chain, either entirely on a
814+
/// single line, or in multi-line format with each cause in the error chain on a new line.
815+
///
814816
/// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the
815817
/// wrapped error be `Send`, `Sync`, or `'static`.
816818
///
817819
/// # Examples
818820
///
819821
/// ```rust
820822
/// #![feature(error_reporter)]
821-
/// #![feature(negative_impls)]
822-
///
823823
/// use std::error::{Error, Report};
824824
/// use std::fmt;
825825
///
826826
/// #[derive(Debug)]
827-
/// struct SuperError<'a> {
828-
/// side: &'a str,
827+
/// struct SuperError {
828+
/// source: SuperErrorSideKick,
829829
/// }
830830
///
831-
/// impl<'a> fmt::Display for SuperError<'a> {
831+
/// impl fmt::Display for SuperError {
832832
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
833-
/// write!(f, "SuperError is here: {}", self.side)
833+
/// write!(f, "SuperError is here!")
834834
/// }
835835
/// }
836836
///
837-
/// impl<'a> Error for SuperError<'a> {}
837+
/// impl Error for SuperError {
838+
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
839+
/// Some(&self.source)
840+
/// }
841+
/// }
838842
///
839-
/// fn main() {
840-
/// let msg = String::from("Huzzah!");
841-
/// let error = SuperError { side: &msg };
842-
/// let report = Report::new(&error).pretty(true);
843+
/// #[derive(Debug)]
844+
/// struct SuperErrorSideKick;
845+
///
846+
/// impl fmt::Display for SuperErrorSideKick {
847+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
848+
/// write!(f, "SuperErrorSideKick is here!")
849+
/// }
850+
/// }
851+
///
852+
/// impl Error for SuperErrorSideKick {}
843853
///
844-
/// println!("{}", report);
854+
/// fn get_super_error() -> Result<(), SuperError> {
855+
/// Err(SuperError { source: SuperErrorSideKick })
856+
/// }
857+
///
858+
/// fn main() {
859+
/// match get_super_error() {
860+
/// Err(e) => {
861+
/// let report = Report::new(e).pretty(true);
862+
/// println!("Error: {}", report);
863+
/// }
864+
/// _ => println!("No error"),
865+
/// }
845866
/// }
846867
/// ```
847-
848868
#[unstable(feature = "error_reporter", issue = "90172")]
849869
pub struct Report<E> {
850870
/// The error being reported.
@@ -865,14 +885,129 @@ where
865885
Report { error, show_backtrace: false, pretty: false }
866886
}
867887

868-
/// Enable pretty-printing the report.
888+
/// Enable pretty-printing the report across multiple lines.
889+
///
890+
/// # Examples
891+
///
892+
/// ```rust
893+
/// #![feature(error_reporter)]
894+
/// use std::error::Report;
895+
/// # use std::error::Error;
896+
/// # use std::fmt;
897+
/// # #[derive(Debug)]
898+
/// # struct SuperError {
899+
/// # source: SuperErrorSideKick,
900+
/// # }
901+
/// # impl fmt::Display for SuperError {
902+
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
903+
/// # write!(f, "SuperError is here!")
904+
/// # }
905+
/// # }
906+
/// # impl Error for SuperError {
907+
/// # fn source(&self) -> Option<&(dyn Error + 'static)> {
908+
/// # Some(&self.source)
909+
/// # }
910+
/// # }
911+
/// # #[derive(Debug)]
912+
/// # struct SuperErrorSideKick;
913+
/// # impl fmt::Display for SuperErrorSideKick {
914+
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
915+
/// # write!(f, "SuperErrorSideKick is here!")
916+
/// # }
917+
/// # }
918+
/// # impl Error for SuperErrorSideKick {}
919+
///
920+
/// let error = SuperError { source: SuperErrorSideKick };
921+
/// let report = Report::new(error).pretty(true);
922+
/// eprintln!("Error: {:?}", report);
923+
/// ```
924+
///
925+
/// This example produces the following output:
926+
///
927+
/// ```console
928+
/// Error: SuperError is here!
929+
///
930+
/// Caused by:
931+
/// SuperErrorSideKick is here!
932+
/// ```
869933
#[unstable(feature = "error_reporter", issue = "90172")]
870934
pub fn pretty(mut self, pretty: bool) -> Self {
871935
self.pretty = pretty;
872936
self
873937
}
874938

875-
/// Enable showing a backtrace for the report.
939+
/// Display backtrace if available when using pretty output format.
940+
///
941+
/// # Examples
942+
///
943+
/// ```rust
944+
/// #![feature(error_reporter)]
945+
/// #![feature(backtrace)]
946+
/// use std::error::{Error, Report};
947+
/// use std::backtrace::Backtrace;
948+
/// use std::fmt;
949+
///
950+
/// #[derive(Debug)]
951+
/// struct SuperError {
952+
/// source: SuperErrorSideKick,
953+
/// }
954+
///
955+
/// impl fmt::Display for SuperError {
956+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
957+
/// write!(f, "SuperError is here!")
958+
/// }
959+
/// }
960+
///
961+
/// impl Error for SuperError {
962+
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
963+
/// Some(&self.source)
964+
/// }
965+
/// }
966+
///
967+
/// #[derive(Debug)]
968+
/// struct SuperErrorSideKick {
969+
/// backtrace: Backtrace,
970+
/// }
971+
///
972+
/// impl fmt::Display for SuperErrorSideKick {
973+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974+
/// write!(f, "SuperErrorSideKick is here!")
975+
/// }
976+
/// }
977+
///
978+
/// impl Error for SuperErrorSideKick {
979+
/// fn backtrace(&self) -> Option<&Backtrace> {
980+
/// Some(&self.backtrace)
981+
/// }
982+
/// }
983+
///
984+
/// let source = SuperErrorSideKick { backtrace: Backtrace::force_capture() };
985+
/// let error = SuperError { source };
986+
/// let report = Report::new(error).pretty(true).show_backtrace(true);
987+
/// eprintln!("Error: {:?}", report);
988+
/// ```
989+
///
990+
/// This example produces something similar to the following output:
991+
///
992+
/// ```console
993+
/// Error: SuperError is here!
994+
///
995+
/// Caused by:
996+
/// SuperErrorSideKick is here!
997+
///
998+
/// Stack backtrace:
999+
/// 0: rust_out::main::_doctest_main_src_error_rs_943_0
1000+
/// 1: rust_out::main
1001+
/// 2: core::ops::function::FnOnce::call_once
1002+
/// 3: std::sys_common::backtrace::__rust_begin_short_backtrace
1003+
/// 4: std::rt::lang_start::{{closure}}
1004+
/// 5: std::panicking::try
1005+
/// 6: std::rt::lang_start_internal
1006+
/// 7: std::rt::lang_start
1007+
/// 8: main
1008+
/// 9: __libc_start_main
1009+
/// 10: _start
1010+
/// ```
8761011
#[unstable(feature = "error_reporter", issue = "90172")]
8771012
pub fn show_backtrace(mut self, show_backtrace: bool) -> Self {
8781013
self.show_backtrace = show_backtrace;
@@ -922,10 +1057,12 @@ where
9221057
writeln!(f)?;
9231058
let mut indented = Indented {
9241059
inner: f,
925-
number: if multiple { Some(ind) } else { None },
926-
started: false,
9271060
};
928-
write!(indented, "{}", error)?;
1061+
if multiple {
1062+
write!(indented, "{: >4}: {}", ind, error)?;
1063+
} else {
1064+
write!(indented, " {}", error)?;
1065+
}
9291066
}
9301067
}
9311068

@@ -979,8 +1116,6 @@ where
9791116
/// Wrapper type for indenting the inner source.
9801117
struct Indented<'a, D> {
9811118
inner: &'a mut D,
982-
number: Option<usize>,
983-
started: bool,
9841119
}
9851120

9861121
impl<T> Write for Indented<'_, T>
@@ -989,19 +1124,9 @@ where
9891124
{
9901125
fn write_str(&mut self, s: &str) -> fmt::Result {
9911126
for (i, line) in s.split('\n').enumerate() {
992-
if !self.started {
993-
self.started = true;
994-
match self.number {
995-
Some(number) => write!(self.inner, "{: >5}: ", number)?,
996-
None => self.inner.write_str(" ")?,
997-
}
998-
} else if i > 0 {
1127+
if i > 0 {
9991128
self.inner.write_char('\n')?;
1000-
if self.number.is_some() {
1001-
self.inner.write_str(" ")?;
1002-
} else {
1003-
self.inner.write_str(" ")?;
1004-
}
1129+
self.inner.write_str(" ")?;
10051130
}
10061131

10071132
self.inner.write_str(line)?;

0 commit comments

Comments
 (0)