@@ -25,7 +25,7 @@ use crate::backtrace::Backtrace;
25
25
use crate :: borrow:: Cow ;
26
26
use crate :: cell;
27
27
use crate :: char;
28
- use crate :: fmt:: { self , Debug , Display } ;
28
+ use crate :: fmt:: { self , Debug , Display , Write } ;
29
29
use crate :: mem:: transmute;
30
30
use crate :: num;
31
31
use crate :: str;
@@ -63,7 +63,7 @@ pub trait Error: Debug + Display {
63
63
///
64
64
/// #[derive(Debug)]
65
65
/// struct SuperError {
66
- /// side : SuperErrorSideKick,
66
+ /// source : SuperErrorSideKick,
67
67
/// }
68
68
///
69
69
/// impl fmt::Display for SuperError {
@@ -74,7 +74,7 @@ pub trait Error: Debug + Display {
74
74
///
75
75
/// impl Error for SuperError {
76
76
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
77
- /// Some(&self.side )
77
+ /// Some(&self.source )
78
78
/// }
79
79
/// }
80
80
///
@@ -90,7 +90,7 @@ pub trait Error: Debug + Display {
90
90
/// impl Error for SuperErrorSideKick {}
91
91
///
92
92
/// fn get_super_error() -> Result<(), SuperError> {
93
- /// Err(SuperError { side : SuperErrorSideKick })
93
+ /// Err(SuperError { source : SuperErrorSideKick })
94
94
/// }
95
95
///
96
96
/// fn main() {
@@ -810,3 +810,642 @@ impl dyn Error + Send + Sync {
810
810
} )
811
811
}
812
812
}
813
+
814
+ /// An error reporter that print's an error and its sources.
815
+ ///
816
+ /// Report also exposes configuration options for formatting the error chain, either entirely on a
817
+ /// single line, or in multi-line format with each cause in the error chain on a new line.
818
+ ///
819
+ /// `Report` only requires that the wrapped error implements `Error`. It doesn't require that the
820
+ /// wrapped error be `Send`, `Sync`, or `'static`.
821
+ ///
822
+ /// # Examples
823
+ ///
824
+ /// ```rust
825
+ /// #![feature(error_reporter)]
826
+ /// use std::error::{Error, Report};
827
+ /// use std::fmt;
828
+ ///
829
+ /// #[derive(Debug)]
830
+ /// struct SuperError {
831
+ /// source: SuperErrorSideKick,
832
+ /// }
833
+ ///
834
+ /// impl fmt::Display for SuperError {
835
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
836
+ /// write!(f, "SuperError is here!")
837
+ /// }
838
+ /// }
839
+ ///
840
+ /// impl Error for SuperError {
841
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
842
+ /// Some(&self.source)
843
+ /// }
844
+ /// }
845
+ ///
846
+ /// #[derive(Debug)]
847
+ /// struct SuperErrorSideKick;
848
+ ///
849
+ /// impl fmt::Display for SuperErrorSideKick {
850
+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
851
+ /// write!(f, "SuperErrorSideKick is here!")
852
+ /// }
853
+ /// }
854
+ ///
855
+ /// impl Error for SuperErrorSideKick {}
856
+ ///
857
+ /// fn get_super_error() -> Result<(), SuperError> {
858
+ /// Err(SuperError { source: SuperErrorSideKick })
859
+ /// }
860
+ ///
861
+ /// fn main() {
862
+ /// match get_super_error() {
863
+ /// Err(e) => println!("Error: {}", Report::new(e)),
864
+ /// _ => println!("No error"),
865
+ /// }
866
+ /// }
867
+ /// ```
868
+ ///
869
+ /// This example produces the following output:
870
+ ///
871
+ /// ```console
872
+ /// Error: SuperError is here!: SuperErrorSideKick is here!
873
+ /// ```
874
+ ///
875
+ /// ## Output consistency
876
+ ///
877
+ /// Report prints the same output via `Display` and `Debug`, so it works well with
878
+ /// [`Result::unwrap`]/[`Result::expect`] which print their `Err` variant via `Debug`:
879
+ ///
880
+ /// ```should_panic
881
+ /// #![feature(error_reporter)]
882
+ /// use std::error::Report;
883
+ /// # use std::error::Error;
884
+ /// # use std::fmt;
885
+ /// # #[derive(Debug)]
886
+ /// # struct SuperError {
887
+ /// # source: SuperErrorSideKick,
888
+ /// # }
889
+ /// # impl fmt::Display for SuperError {
890
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
891
+ /// # write!(f, "SuperError is here!")
892
+ /// # }
893
+ /// # }
894
+ /// # impl Error for SuperError {
895
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
896
+ /// # Some(&self.source)
897
+ /// # }
898
+ /// # }
899
+ /// # #[derive(Debug)]
900
+ /// # struct SuperErrorSideKick;
901
+ /// # impl fmt::Display for SuperErrorSideKick {
902
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
903
+ /// # write!(f, "SuperErrorSideKick is here!")
904
+ /// # }
905
+ /// # }
906
+ /// # impl Error for SuperErrorSideKick {}
907
+ /// # fn get_super_error() -> Result<(), SuperError> {
908
+ /// # Err(SuperError { source: SuperErrorSideKick })
909
+ /// # }
910
+ ///
911
+ /// get_super_error().map_err(Report::new).unwrap();
912
+ /// ```
913
+ ///
914
+ /// This example produces the following output:
915
+ ///
916
+ /// ```console
917
+ /// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
918
+ /// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
919
+ /// ```
920
+ ///
921
+ /// ## Return from `main`
922
+ ///
923
+ /// `Report` also implements `From` for all types that implement [`Error`], this when combined with
924
+ /// the `Debug` output means `Report` is an ideal starting place for formatting errors returned
925
+ /// from `main`.
926
+ ///
927
+ /// ```should_panic
928
+ /// #![feature(error_reporter)]
929
+ /// use std::error::Report;
930
+ /// # use std::error::Error;
931
+ /// # use std::fmt;
932
+ /// # #[derive(Debug)]
933
+ /// # struct SuperError {
934
+ /// # source: SuperErrorSideKick,
935
+ /// # }
936
+ /// # impl fmt::Display for SuperError {
937
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
938
+ /// # write!(f, "SuperError is here!")
939
+ /// # }
940
+ /// # }
941
+ /// # impl Error for SuperError {
942
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
943
+ /// # Some(&self.source)
944
+ /// # }
945
+ /// # }
946
+ /// # #[derive(Debug)]
947
+ /// # struct SuperErrorSideKick;
948
+ /// # impl fmt::Display for SuperErrorSideKick {
949
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
950
+ /// # write!(f, "SuperErrorSideKick is here!")
951
+ /// # }
952
+ /// # }
953
+ /// # impl Error for SuperErrorSideKick {}
954
+ /// # fn get_super_error() -> Result<(), SuperError> {
955
+ /// # Err(SuperError { source: SuperErrorSideKick })
956
+ /// # }
957
+ ///
958
+ /// fn main() -> Result<(), Report> {
959
+ /// get_super_error()?;
960
+ /// Ok(())
961
+ /// }
962
+ /// ```
963
+ ///
964
+ /// This example produces the following output:
965
+ ///
966
+ /// ```console
967
+ /// Error: SuperError is here!: SuperErrorSideKick is here!
968
+ /// ```
969
+ ///
970
+ /// **Note**: `Report`s constructed via `?` and `From` will be configured to use the single line
971
+ /// output format, if you want to make sure your `Report`s are pretty printed and include backtrace
972
+ /// you will need to manually convert and enable those flags.
973
+ ///
974
+ /// ```should_panic
975
+ /// #![feature(error_reporter)]
976
+ /// use std::error::Report;
977
+ /// # use std::error::Error;
978
+ /// # use std::fmt;
979
+ /// # #[derive(Debug)]
980
+ /// # struct SuperError {
981
+ /// # source: SuperErrorSideKick,
982
+ /// # }
983
+ /// # impl fmt::Display for SuperError {
984
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
985
+ /// # write!(f, "SuperError is here!")
986
+ /// # }
987
+ /// # }
988
+ /// # impl Error for SuperError {
989
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
990
+ /// # Some(&self.source)
991
+ /// # }
992
+ /// # }
993
+ /// # #[derive(Debug)]
994
+ /// # struct SuperErrorSideKick;
995
+ /// # impl fmt::Display for SuperErrorSideKick {
996
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
997
+ /// # write!(f, "SuperErrorSideKick is here!")
998
+ /// # }
999
+ /// # }
1000
+ /// # impl Error for SuperErrorSideKick {}
1001
+ /// # fn get_super_error() -> Result<(), SuperError> {
1002
+ /// # Err(SuperError { source: SuperErrorSideKick })
1003
+ /// # }
1004
+ ///
1005
+ /// fn main() -> Result<(), Report> {
1006
+ /// get_super_error()
1007
+ /// .map_err(Report::from)
1008
+ /// .map_err(|r| r.pretty(true).show_backtrace(true))?;
1009
+ /// Ok(())
1010
+ /// }
1011
+ /// ```
1012
+ ///
1013
+ /// This example produces the following output:
1014
+ ///
1015
+ /// ```console
1016
+ /// Error: SuperError is here!
1017
+ ///
1018
+ /// Caused by:
1019
+ /// SuperErrorSideKick is here!
1020
+ /// ```
1021
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1022
+ pub struct Report < E = Box < dyn Error > > {
1023
+ /// The error being reported.
1024
+ error : E ,
1025
+ /// Whether a backtrace should be included as part of the report.
1026
+ show_backtrace : bool ,
1027
+ /// Whether the report should be pretty-printed.
1028
+ pretty : bool ,
1029
+ }
1030
+
1031
+ impl < E > Report < E >
1032
+ where
1033
+ Report < E > : From < E > ,
1034
+ {
1035
+ /// Create a new `Report` from an input error.
1036
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1037
+ pub fn new ( error : E ) -> Report < E > {
1038
+ Self :: from ( error)
1039
+ }
1040
+ }
1041
+
1042
+ impl < E > Report < E > {
1043
+ /// Enable pretty-printing the report across multiple lines.
1044
+ ///
1045
+ /// # Examples
1046
+ ///
1047
+ /// ```rust
1048
+ /// #![feature(error_reporter)]
1049
+ /// use std::error::Report;
1050
+ /// # use std::error::Error;
1051
+ /// # use std::fmt;
1052
+ /// # #[derive(Debug)]
1053
+ /// # struct SuperError {
1054
+ /// # source: SuperErrorSideKick,
1055
+ /// # }
1056
+ /// # impl fmt::Display for SuperError {
1057
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1058
+ /// # write!(f, "SuperError is here!")
1059
+ /// # }
1060
+ /// # }
1061
+ /// # impl Error for SuperError {
1062
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1063
+ /// # Some(&self.source)
1064
+ /// # }
1065
+ /// # }
1066
+ /// # #[derive(Debug)]
1067
+ /// # struct SuperErrorSideKick;
1068
+ /// # impl fmt::Display for SuperErrorSideKick {
1069
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1070
+ /// # write!(f, "SuperErrorSideKick is here!")
1071
+ /// # }
1072
+ /// # }
1073
+ /// # impl Error for SuperErrorSideKick {}
1074
+ ///
1075
+ /// let error = SuperError { source: SuperErrorSideKick };
1076
+ /// let report = Report::new(error).pretty(true);
1077
+ /// eprintln!("Error: {:?}", report);
1078
+ /// ```
1079
+ ///
1080
+ /// This example produces the following output:
1081
+ ///
1082
+ /// ```console
1083
+ /// Error: SuperError is here!
1084
+ ///
1085
+ /// Caused by:
1086
+ /// SuperErrorSideKick is here!
1087
+ /// ```
1088
+ ///
1089
+ /// When there are multiple source errors the causes will be numbered in order of iteration
1090
+ /// starting from the outermost error.
1091
+ ///
1092
+ /// ```rust
1093
+ /// #![feature(error_reporter)]
1094
+ /// use std::error::Report;
1095
+ /// # use std::error::Error;
1096
+ /// # use std::fmt;
1097
+ /// # #[derive(Debug)]
1098
+ /// # struct SuperError {
1099
+ /// # source: SuperErrorSideKick,
1100
+ /// # }
1101
+ /// # impl fmt::Display for SuperError {
1102
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1103
+ /// # write!(f, "SuperError is here!")
1104
+ /// # }
1105
+ /// # }
1106
+ /// # impl Error for SuperError {
1107
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1108
+ /// # Some(&self.source)
1109
+ /// # }
1110
+ /// # }
1111
+ /// # #[derive(Debug)]
1112
+ /// # struct SuperErrorSideKick {
1113
+ /// # source: SuperErrorSideKickSideKick,
1114
+ /// # }
1115
+ /// # impl fmt::Display for SuperErrorSideKick {
1116
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1117
+ /// # write!(f, "SuperErrorSideKick is here!")
1118
+ /// # }
1119
+ /// # }
1120
+ /// # impl Error for SuperErrorSideKick {
1121
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1122
+ /// # Some(&self.source)
1123
+ /// # }
1124
+ /// # }
1125
+ /// # #[derive(Debug)]
1126
+ /// # struct SuperErrorSideKickSideKick;
1127
+ /// # impl fmt::Display for SuperErrorSideKickSideKick {
1128
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1129
+ /// # write!(f, "SuperErrorSideKickSideKick is here!")
1130
+ /// # }
1131
+ /// # }
1132
+ /// # impl Error for SuperErrorSideKickSideKick { }
1133
+ ///
1134
+ /// let source = SuperErrorSideKickSideKick;
1135
+ /// let source = SuperErrorSideKick { source };
1136
+ /// let error = SuperError { source };
1137
+ /// let report = Report::new(error).pretty(true);
1138
+ /// eprintln!("Error: {:?}", report);
1139
+ /// ```
1140
+ ///
1141
+ /// This example produces the following output:
1142
+ ///
1143
+ /// ```console
1144
+ /// Error: SuperError is here!
1145
+ ///
1146
+ /// Caused by:
1147
+ /// 0: SuperErrorSideKick is here!
1148
+ /// 1: SuperErrorSideKickSideKick is here!
1149
+ /// ```
1150
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1151
+ pub fn pretty ( mut self , pretty : bool ) -> Self {
1152
+ self . pretty = pretty;
1153
+ self
1154
+ }
1155
+
1156
+ /// Display backtrace if available when using pretty output format.
1157
+ ///
1158
+ /// # Examples
1159
+ ///
1160
+ /// **Note**: Report will search for the first `Backtrace` it can find starting from the
1161
+ /// outermost error. In this example it will display the backtrace from the second error in the
1162
+ /// chain, `SuperErrorSideKick`.
1163
+ ///
1164
+ /// ```rust
1165
+ /// #![feature(error_reporter)]
1166
+ /// #![feature(backtrace)]
1167
+ /// # use std::error::Error;
1168
+ /// # use std::fmt;
1169
+ /// use std::error::Report;
1170
+ /// use std::backtrace::Backtrace;
1171
+ ///
1172
+ /// # #[derive(Debug)]
1173
+ /// # struct SuperError {
1174
+ /// # source: SuperErrorSideKick,
1175
+ /// # }
1176
+ /// # impl fmt::Display for SuperError {
1177
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1178
+ /// # write!(f, "SuperError is here!")
1179
+ /// # }
1180
+ /// # }
1181
+ /// # impl Error for SuperError {
1182
+ /// # fn source(&self) -> Option<&(dyn Error + 'static)> {
1183
+ /// # Some(&self.source)
1184
+ /// # }
1185
+ /// # }
1186
+ /// #[derive(Debug)]
1187
+ /// struct SuperErrorSideKick {
1188
+ /// backtrace: Backtrace,
1189
+ /// }
1190
+ ///
1191
+ /// impl SuperErrorSideKick {
1192
+ /// fn new() -> SuperErrorSideKick {
1193
+ /// SuperErrorSideKick { backtrace: Backtrace::force_capture() }
1194
+ /// }
1195
+ /// }
1196
+ ///
1197
+ /// impl Error for SuperErrorSideKick {
1198
+ /// fn backtrace(&self) -> Option<&Backtrace> {
1199
+ /// Some(&self.backtrace)
1200
+ /// }
1201
+ /// }
1202
+ ///
1203
+ /// // The rest of the example is unchanged ...
1204
+ /// # impl fmt::Display for SuperErrorSideKick {
1205
+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1206
+ /// # write!(f, "SuperErrorSideKick is here!")
1207
+ /// # }
1208
+ /// # }
1209
+ ///
1210
+ /// let source = SuperErrorSideKick::new();
1211
+ /// let error = SuperError { source };
1212
+ /// let report = Report::new(error).pretty(true).show_backtrace(true);
1213
+ /// eprintln!("Error: {:?}", report);
1214
+ /// ```
1215
+ ///
1216
+ /// This example produces something similar to the following output:
1217
+ ///
1218
+ /// ```console
1219
+ /// Error: SuperError is here!
1220
+ ///
1221
+ /// Caused by:
1222
+ /// SuperErrorSideKick is here!
1223
+ ///
1224
+ /// Stack backtrace:
1225
+ /// 0: rust_out::main::_doctest_main_src_error_rs_1158_0::SuperErrorSideKick::new
1226
+ /// 1: rust_out::main::_doctest_main_src_error_rs_1158_0
1227
+ /// 2: rust_out::main
1228
+ /// 3: core::ops::function::FnOnce::call_once
1229
+ /// 4: std::sys_common::backtrace::__rust_begin_short_backtrace
1230
+ /// 5: std::rt::lang_start::{{closure}}
1231
+ /// 6: std::panicking::try
1232
+ /// 7: std::rt::lang_start_internal
1233
+ /// 8: std::rt::lang_start
1234
+ /// 9: main
1235
+ /// 10: __libc_start_main
1236
+ /// 11: _start
1237
+ /// ```
1238
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1239
+ pub fn show_backtrace ( mut self , show_backtrace : bool ) -> Self {
1240
+ self . show_backtrace = show_backtrace;
1241
+ self
1242
+ }
1243
+ }
1244
+
1245
+ impl < E > Report < E >
1246
+ where
1247
+ E : Error ,
1248
+ {
1249
+ fn backtrace ( & self ) -> Option < & Backtrace > {
1250
+ // have to grab the backtrace on the first error directly since that error may not be
1251
+ // 'static
1252
+ let backtrace = self . error . backtrace ( ) ;
1253
+ let backtrace = backtrace. or_else ( || {
1254
+ self . error
1255
+ . source ( )
1256
+ . map ( |source| source. chain ( ) . find_map ( |source| source. backtrace ( ) ) )
1257
+ . flatten ( )
1258
+ } ) ;
1259
+ backtrace
1260
+ }
1261
+
1262
+ /// Format the report as a single line.
1263
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1264
+ fn fmt_singleline ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1265
+ write ! ( f, "{}" , self . error) ?;
1266
+
1267
+ let sources = self . error . source ( ) . into_iter ( ) . flat_map ( <dyn Error >:: chain) ;
1268
+
1269
+ for cause in sources {
1270
+ write ! ( f, ": {}" , cause) ?;
1271
+ }
1272
+
1273
+ Ok ( ( ) )
1274
+ }
1275
+
1276
+ /// Format the report as multiple lines, with each error cause on its own line.
1277
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1278
+ fn fmt_multiline ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1279
+ let error = & self . error ;
1280
+
1281
+ write ! ( f, "{}" , error) ?;
1282
+
1283
+ if let Some ( cause) = error. source ( ) {
1284
+ write ! ( f, "\n \n Caused by:" ) ?;
1285
+
1286
+ let multiple = cause. source ( ) . is_some ( ) ;
1287
+
1288
+ for ( ind, error) in cause. chain ( ) . enumerate ( ) {
1289
+ writeln ! ( f) ?;
1290
+ let mut indented = Indented { inner : f } ;
1291
+ if multiple {
1292
+ write ! ( indented, "{: >4}: {}" , ind, error) ?;
1293
+ } else {
1294
+ write ! ( indented, " {}" , error) ?;
1295
+ }
1296
+ }
1297
+ }
1298
+
1299
+ if self . show_backtrace {
1300
+ let backtrace = self . backtrace ( ) ;
1301
+
1302
+ if let Some ( backtrace) = backtrace {
1303
+ let backtrace = backtrace. to_string ( ) ;
1304
+
1305
+ f. write_str ( "\n \n Stack backtrace:\n " ) ?;
1306
+ f. write_str ( backtrace. trim_end ( ) ) ?;
1307
+ }
1308
+ }
1309
+
1310
+ Ok ( ( ) )
1311
+ }
1312
+ }
1313
+
1314
+ impl Report < Box < dyn Error > > {
1315
+ fn backtrace ( & self ) -> Option < & Backtrace > {
1316
+ // have to grab the backtrace on the first error directly since that error may not be
1317
+ // 'static
1318
+ let backtrace = self . error . backtrace ( ) ;
1319
+ let backtrace = backtrace. or_else ( || {
1320
+ self . error
1321
+ . source ( )
1322
+ . map ( |source| source. chain ( ) . find_map ( |source| source. backtrace ( ) ) )
1323
+ . flatten ( )
1324
+ } ) ;
1325
+ backtrace
1326
+ }
1327
+
1328
+ /// Format the report as a single line.
1329
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1330
+ fn fmt_singleline ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1331
+ write ! ( f, "{}" , self . error) ?;
1332
+
1333
+ let sources = self . error . source ( ) . into_iter ( ) . flat_map ( <dyn Error >:: chain) ;
1334
+
1335
+ for cause in sources {
1336
+ write ! ( f, ": {}" , cause) ?;
1337
+ }
1338
+
1339
+ Ok ( ( ) )
1340
+ }
1341
+
1342
+ /// Format the report as multiple lines, with each error cause on its own line.
1343
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1344
+ fn fmt_multiline ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1345
+ let error = & self . error ;
1346
+
1347
+ write ! ( f, "{}" , error) ?;
1348
+
1349
+ if let Some ( cause) = error. source ( ) {
1350
+ write ! ( f, "\n \n Caused by:" ) ?;
1351
+
1352
+ let multiple = cause. source ( ) . is_some ( ) ;
1353
+
1354
+ for ( ind, error) in cause. chain ( ) . enumerate ( ) {
1355
+ writeln ! ( f) ?;
1356
+ let mut indented = Indented { inner : f } ;
1357
+ if multiple {
1358
+ write ! ( indented, "{: >4}: {}" , ind, error) ?;
1359
+ } else {
1360
+ write ! ( indented, " {}" , error) ?;
1361
+ }
1362
+ }
1363
+ }
1364
+
1365
+ if self . show_backtrace {
1366
+ let backtrace = self . backtrace ( ) ;
1367
+
1368
+ if let Some ( backtrace) = backtrace {
1369
+ let backtrace = backtrace. to_string ( ) ;
1370
+
1371
+ f. write_str ( "\n \n Stack backtrace:\n " ) ?;
1372
+ f. write_str ( backtrace. trim_end ( ) ) ?;
1373
+ }
1374
+ }
1375
+
1376
+ Ok ( ( ) )
1377
+ }
1378
+ }
1379
+
1380
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1381
+ impl < E > From < E > for Report < E >
1382
+ where
1383
+ E : Error ,
1384
+ {
1385
+ fn from ( error : E ) -> Self {
1386
+ Report { error, show_backtrace : false , pretty : false }
1387
+ }
1388
+ }
1389
+
1390
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1391
+ impl < ' a , E > From < E > for Report < Box < dyn Error + ' a > >
1392
+ where
1393
+ E : Error + ' a ,
1394
+ {
1395
+ fn from ( error : E ) -> Self {
1396
+ let error = box error;
1397
+ Report { error, show_backtrace : false , pretty : false }
1398
+ }
1399
+ }
1400
+
1401
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1402
+ impl < E > fmt:: Display for Report < E >
1403
+ where
1404
+ E : Error ,
1405
+ {
1406
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1407
+ if self . pretty { self . fmt_multiline ( f) } else { self . fmt_singleline ( f) }
1408
+ }
1409
+ }
1410
+
1411
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1412
+ impl fmt:: Display for Report < Box < dyn Error > > {
1413
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1414
+ if self . pretty { self . fmt_multiline ( f) } else { self . fmt_singleline ( f) }
1415
+ }
1416
+ }
1417
+
1418
+ // This type intentionally outputs the same format for `Display` and `Debug`for
1419
+ // situations where you unwrap a `Report` or return it from main.
1420
+ #[ unstable( feature = "error_reporter" , issue = "90172" ) ]
1421
+ impl < E > fmt:: Debug for Report < E >
1422
+ where
1423
+ Report < E > : fmt:: Display ,
1424
+ {
1425
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1426
+ fmt:: Display :: fmt ( self , f)
1427
+ }
1428
+ }
1429
+
1430
+ /// Wrapper type for indenting the inner source.
1431
+ struct Indented < ' a , D > {
1432
+ inner : & ' a mut D ,
1433
+ }
1434
+
1435
+ impl < T > Write for Indented < ' _ , T >
1436
+ where
1437
+ T : Write ,
1438
+ {
1439
+ fn write_str ( & mut self , s : & str ) -> fmt:: Result {
1440
+ for ( i, line) in s. split ( '\n' ) . enumerate ( ) {
1441
+ if i > 0 {
1442
+ self . inner . write_char ( '\n' ) ?;
1443
+ self . inner . write_str ( " " ) ?;
1444
+ }
1445
+
1446
+ self . inner . write_str ( line) ?;
1447
+ }
1448
+
1449
+ Ok ( ( ) )
1450
+ }
1451
+ }
0 commit comments