1 use tracing::subscriber::with_default;
2 use tracing::Level;
3 use tracing_attributes::instrument;
4 use tracing_mock::*;
5 use tracing_subscriber::filter::EnvFilter;
6 use tracing_subscriber::layer::SubscriberExt;
7
8 use std::convert::TryFrom;
9 use std::num::TryFromIntError;
10
11 #[instrument(err)]
err() -> Result<u8, TryFromIntError>12 fn err() -> Result<u8, TryFromIntError> {
13 u8::try_from(1234)
14 }
15
16 #[instrument(err)]
err_suspicious_else() -> Result<u8, TryFromIntError>17 fn err_suspicious_else() -> Result<u8, TryFromIntError> {
18 {}
19 u8::try_from(1234)
20 }
21
22 #[test]
test()23 fn test() {
24 let span = span::mock().named("err");
25 let (subscriber, handle) = subscriber::mock()
26 .new_span(span.clone())
27 .enter(span.clone())
28 .event(event::mock().at_level(Level::ERROR))
29 .exit(span.clone())
30 .drop_span(span)
31 .done()
32 .run_with_handle();
33 with_default(subscriber, || err().ok());
34 handle.assert_finished();
35 }
36
37 #[instrument(err)]
err_async(polls: usize) -> Result<u8, TryFromIntError>38 async fn err_async(polls: usize) -> Result<u8, TryFromIntError> {
39 let future = PollN::new_ok(polls);
40 tracing::trace!(awaiting = true);
41 future.await.ok();
42 u8::try_from(1234)
43 }
44
45 #[test]
test_async()46 fn test_async() {
47 let span = span::mock().named("err_async");
48 let (subscriber, handle) = subscriber::mock()
49 .new_span(span.clone())
50 .enter(span.clone())
51 .event(
52 event::mock()
53 .with_fields(field::mock("awaiting").with_value(&true))
54 .at_level(Level::TRACE),
55 )
56 .exit(span.clone())
57 .enter(span.clone())
58 .event(event::mock().at_level(Level::ERROR))
59 .exit(span.clone())
60 .drop_span(span)
61 .done()
62 .run_with_handle();
63 with_default(subscriber, || {
64 block_on_future(async { err_async(2).await }).ok();
65 });
66 handle.assert_finished();
67 }
68
69 #[instrument(err)]
err_mut(out: &mut u8) -> Result<(), TryFromIntError>70 fn err_mut(out: &mut u8) -> Result<(), TryFromIntError> {
71 *out = u8::try_from(1234)?;
72 Ok(())
73 }
74
75 #[test]
test_mut()76 fn test_mut() {
77 let span = span::mock().named("err_mut");
78 let (subscriber, handle) = subscriber::mock()
79 .new_span(span.clone())
80 .enter(span.clone())
81 .event(event::mock().at_level(Level::ERROR))
82 .exit(span.clone())
83 .drop_span(span)
84 .done()
85 .run_with_handle();
86 with_default(subscriber, || err_mut(&mut 0).ok());
87 handle.assert_finished();
88 }
89
90 #[instrument(err)]
err_mut_async(polls: usize, out: &mut u8) -> Result<(), TryFromIntError>91 async fn err_mut_async(polls: usize, out: &mut u8) -> Result<(), TryFromIntError> {
92 let future = PollN::new_ok(polls);
93 tracing::trace!(awaiting = true);
94 future.await.ok();
95 *out = u8::try_from(1234)?;
96 Ok(())
97 }
98
99 #[test]
test_mut_async()100 fn test_mut_async() {
101 let span = span::mock().named("err_mut_async");
102 let (subscriber, handle) = subscriber::mock()
103 .new_span(span.clone())
104 .enter(span.clone())
105 .event(
106 event::mock()
107 .with_fields(field::mock("awaiting").with_value(&true))
108 .at_level(Level::TRACE),
109 )
110 .exit(span.clone())
111 .enter(span.clone())
112 .event(event::mock().at_level(Level::ERROR))
113 .exit(span.clone())
114 .drop_span(span)
115 .done()
116 .run_with_handle();
117 with_default(subscriber, || {
118 block_on_future(async { err_mut_async(2, &mut 0).await }).ok();
119 });
120 handle.assert_finished();
121 }
122
123 #[test]
impl_trait_return_type()124 fn impl_trait_return_type() {
125 // Reproduces https://github.com/tokio-rs/tracing/issues/1227
126
127 #[instrument(err)]
128 fn returns_impl_trait(x: usize) -> Result<impl Iterator<Item = usize>, String> {
129 Ok(0..x)
130 }
131
132 let span = span::mock().named("returns_impl_trait");
133
134 let (subscriber, handle) = subscriber::mock()
135 .new_span(
136 span.clone()
137 .with_field(field::mock("x").with_value(&10usize).only()),
138 )
139 .enter(span.clone())
140 .exit(span.clone())
141 .drop_span(span)
142 .done()
143 .run_with_handle();
144
145 with_default(subscriber, || {
146 for _ in returns_impl_trait(10).unwrap() {
147 // nop
148 }
149 });
150
151 handle.assert_finished();
152 }
153
154 #[instrument(err(Debug))]
err_dbg() -> Result<u8, TryFromIntError>155 fn err_dbg() -> Result<u8, TryFromIntError> {
156 u8::try_from(1234)
157 }
158
159 #[test]
test_err_dbg()160 fn test_err_dbg() {
161 let span = span::mock().named("err_dbg");
162 let (subscriber, handle) = subscriber::mock()
163 .new_span(span.clone())
164 .enter(span.clone())
165 .event(
166 event::mock().at_level(Level::ERROR).with_fields(
167 field::mock("error")
168 // use the actual error value that will be emitted, so
169 // that this test doesn't break if the standard library
170 // changes the `fmt::Debug` output from the error type
171 // in the future.
172 .with_value(&tracing::field::debug(u8::try_from(1234).unwrap_err())),
173 ),
174 )
175 .exit(span.clone())
176 .drop_span(span)
177 .done()
178 .run_with_handle();
179 with_default(subscriber, || err_dbg().ok());
180 handle.assert_finished();
181 }
182
183 #[test]
test_err_display_default()184 fn test_err_display_default() {
185 let span = span::mock().named("err");
186 let (subscriber, handle) = subscriber::mock()
187 .new_span(span.clone())
188 .enter(span.clone())
189 .event(
190 event::mock().at_level(Level::ERROR).with_fields(
191 field::mock("error")
192 // by default, errors will be emitted with their display values
193 .with_value(&tracing::field::display(u8::try_from(1234).unwrap_err())),
194 ),
195 )
196 .exit(span.clone())
197 .drop_span(span)
198 .done()
199 .run_with_handle();
200 with_default(subscriber, || err().ok());
201 handle.assert_finished();
202 }
203
204 #[test]
test_err_custom_target()205 fn test_err_custom_target() {
206 let filter: EnvFilter = "my_target=error".parse().expect("filter should parse");
207 let span = span::mock().named("error_span").with_target("my_target");
208
209 let (subscriber, handle) = subscriber::mock()
210 .new_span(span.clone())
211 .enter(span.clone())
212 .event(
213 event::mock()
214 .at_level(Level::ERROR)
215 .with_target("my_target"),
216 )
217 .exit(span.clone())
218 .drop_span(span)
219 .done()
220 .run_with_handle();
221
222 let subscriber = subscriber.with(filter);
223
224 with_default(subscriber, || {
225 let error_span = tracing::error_span!(target: "my_target", "error_span");
226
227 {
228 let _enter = error_span.enter();
229 tracing::error!(target: "my_target", "This should display")
230 }
231 });
232 handle.assert_finished();
233 }
234