4 #[derive(Debug, PartialEq)]
6 #[derive(Debug, PartialEq)]
9 impl fmt
::Display
for A
{
10 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
14 impl fmt
::Display
for B
{
15 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
26 let a
= &mut a
as &mut (dyn Error
+ '
static);
27 assert_eq
!(a
.downcast_ref
::<A
>(), Some(&A
));
28 assert_eq
!(a
.downcast_ref
::<B
>(), None
);
29 assert_eq
!(a
.downcast_mut
::<A
>(), Some(&mut A
));
30 assert_eq
!(a
.downcast_mut
::<B
>(), None
);
32 let a
: Box
<dyn Error
> = Box
::new(A
);
33 match a
.downcast
::<B
>() {
34 Ok(..) => panic
!("expected error"),
35 Err(e
) => assert_eq
!(*e
.downcast
::<A
>().unwrap(), A
),
39 use crate::backtrace
::Backtrace
;
40 use crate::error
::Report
;
44 source
: SuperErrorSideKick
,
47 impl fmt
::Display
for SuperError
{
48 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
49 write
!(f
, "SuperError is here!")
53 impl Error
for SuperError
{
54 fn source(&self) -> Option
<&(dyn Error
+ '
static)> {
60 struct SuperErrorSideKick
;
62 impl fmt
::Display
for SuperErrorSideKick
{
63 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
64 write
!(f
, "SuperErrorSideKick is here!")
68 impl Error
for SuperErrorSideKick {}
71 fn single_line_formatting() {
72 let error
= SuperError { source: SuperErrorSideKick }
;
73 let report
= Report
::new(&error
);
74 let actual
= report
.to_string();
75 let expected
= String
::from("SuperError is here!: SuperErrorSideKick is here!");
77 assert_eq
!(expected
, actual
);
81 fn multi_line_formatting() {
82 let error
= SuperError { source: SuperErrorSideKick }
;
83 let report
= Report
::new(&error
).pretty(true);
84 let actual
= report
.to_string();
85 let expected
= String
::from(
90 SuperErrorSideKick is here!",
93 assert_eq
!(expected
, actual
);
97 fn error_with_no_sources_formats_single_line_correctly() {
98 let report
= Report
::new(SuperErrorSideKick
);
99 let actual
= report
.to_string();
100 let expected
= String
::from("SuperErrorSideKick is here!");
102 assert_eq
!(expected
, actual
);
106 fn error_with_no_sources_formats_multi_line_correctly() {
107 let report
= Report
::new(SuperErrorSideKick
).pretty(true);
108 let actual
= report
.to_string();
109 let expected
= String
::from("SuperErrorSideKick is here!");
111 assert_eq
!(expected
, actual
);
115 fn error_with_backtrace_outputs_correctly_with_one_source() {
116 let trace
= Backtrace
::force_capture();
117 let expected
= format
!(
119 The source of the error
128 let error
= GenericError
::new("Error with backtrace");
129 let mut error
= GenericError
::new_with_source("The source of the error", error
);
130 error
.backtrace
= Some(trace
);
131 let report
= Report
::new(error
).pretty(true).show_backtrace(true);
133 println
!("Error: {report}");
134 assert_eq
!(expected
.trim_end(), report
.to_string());
138 fn error_with_backtrace_outputs_correctly_with_two_sources() {
139 let trace
= Backtrace
::force_capture();
140 let expected
= format
!(
142 Error with two sources
145 0: The source of the error
146 1: Error with backtrace
152 let mut error
= GenericError
::new("Error with backtrace");
153 error
.backtrace
= Some(trace
);
154 let error
= GenericError
::new_with_source("The source of the error", error
);
155 let error
= GenericError
::new_with_source("Error with two sources", error
);
156 let report
= Report
::new(error
).pretty(true).show_backtrace(true);
158 println
!("Error: {report}");
159 assert_eq
!(expected
.trim_end(), report
.to_string());
163 struct GenericError
<D
> {
165 backtrace
: Option
<Backtrace
>,
166 source
: Option
<Box
<dyn Error
+ '
static>>,
169 impl<D
> GenericError
<D
> {
170 fn new(message
: D
) -> GenericError
<D
> {
171 Self { message, backtrace: None, source: None }
174 fn new_with_source
<E
>(message
: D
, source
: E
) -> GenericError
<D
>
178 let source
: Box
<dyn Error
+ '
static> = Box
::new(source
);
179 let source
= Some(source
);
180 GenericError { message, backtrace: None, source }
184 impl<D
> fmt
::Display
for GenericError
<D
>
188 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
189 fmt
::Display
::fmt(&self.message
, f
)
193 impl<D
> Error
for GenericError
<D
>
195 D
: fmt
::Debug
+ fmt
::Display
,
197 fn source(&self) -> Option
<&(dyn Error
+ '
static)> {
198 self.source
.as_deref()
201 fn backtrace(&self) -> Option
<&Backtrace
> {
202 self.backtrace
.as_ref()
207 fn error_formats_single_line_with_rude_display_impl() {
211 impl fmt
::Display
for MyMessage
{
212 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
213 f
.write_str("line 1\nline 2")?
;
214 f
.write_str("\nline 3\nline 4\n")?
;
215 f
.write_str("line 5\nline 6")?
;
220 let error
= GenericError
::new(MyMessage
);
221 let error
= GenericError
::new_with_source(MyMessage
, error
);
222 let error
= GenericError
::new_with_source(MyMessage
, error
);
223 let error
= GenericError
::new_with_source(MyMessage
, error
);
224 let report
= Report
::new(error
);
248 let actual
= report
.to_string();
249 assert_eq
!(expected
, actual
);
253 fn error_formats_multi_line_with_rude_display_impl() {
257 impl fmt
::Display
for MyMessage
{
258 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
259 f
.write_str("line 1\nline 2")?
;
260 f
.write_str("\nline 3\nline 4\n")?
;
261 f
.write_str("line 5\nline 6")?
;
266 let error
= GenericError
::new(MyMessage
);
267 let error
= GenericError
::new_with_source(MyMessage
, error
);
268 let error
= GenericError
::new_with_source(MyMessage
, error
);
269 let error
= GenericError
::new_with_source(MyMessage
, error
);
270 let report
= Report
::new(error
).pretty(true);
271 let expected
= "line 1
298 let actual
= report
.to_string();
299 assert_eq
!(expected
, actual
);
303 fn errors_that_start_with_newline_formats_correctly() {
307 impl fmt
::Display
for MyMessage
{
308 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
309 f
.write_str("\nThe message\n")
313 let error
= GenericError
::new(MyMessage
);
314 let error
= GenericError
::new_with_source(MyMessage
, error
);
315 let error
= GenericError
::new_with_source(MyMessage
, error
);
316 let report
= Report
::new(error
).pretty(true);
329 let actual
= report
.to_string();
330 assert_eq
!(expected
, actual
);
334 fn errors_with_multiple_writes_on_same_line_dont_insert_erroneous_newlines() {
338 impl fmt
::Display
for MyMessage
{
339 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
340 f
.write_str("The message")?
;
341 f
.write_str(" goes on")?
;
342 f
.write_str(" and on.")
346 let error
= GenericError
::new(MyMessage
);
347 let error
= GenericError
::new_with_source(MyMessage
, error
);
348 let error
= GenericError
::new_with_source(MyMessage
, error
);
349 let report
= Report
::new(error
).pretty(true);
351 The message goes on and on.
354 0: The message goes on and on.
355 1: The message goes on and on.";
357 let actual
= report
.to_string();
358 println
!("{actual}");
359 assert_eq
!(expected
, actual
);
363 fn errors_with_string_interpolation_formats_correctly() {
365 struct MyMessage(usize);
367 impl fmt
::Display
for MyMessage
{
368 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
369 write
!(f
, "Got an error code: ({}). ", self.0)?
;
370 write
!(f
, "What would you like to do in response?")
374 let error
= GenericError
::new(MyMessage(10));
375 let error
= GenericError
::new_with_source(MyMessage(20), error
);
376 let report
= Report
::new(error
).pretty(true);
378 Got an error code: (20). What would you like to do in response?
381 Got an error code: (10). What would you like to do in response?";
382 let actual
= report
.to_string();
383 assert_eq
!(expected
, actual
);
387 fn empty_lines_mid_message() {
391 impl fmt
::Display
for MyMessage
{
392 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
393 f
.write_str("line 1\n\nline 2")
397 let error
= GenericError
::new(MyMessage
);
398 let error
= GenericError
::new_with_source(MyMessage
, error
);
399 let error
= GenericError
::new_with_source(MyMessage
, error
);
400 let report
= Report
::new(error
).pretty(true);
414 let actual
= report
.to_string();
415 assert_eq
!(expected
, actual
);
419 fn only_one_source() {
423 impl fmt
::Display
for MyMessage
{
424 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
425 f
.write_str("line 1\nline 2")
429 let error
= GenericError
::new(MyMessage
);
430 let error
= GenericError
::new_with_source(MyMessage
, error
);
431 let report
= Report
::new(error
).pretty(true);
440 let actual
= report
.to_string();
441 assert_eq
!(expected
, actual
);