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 = expect::span().named("err");
25 let (subscriber, handle) = subscriber::mock()
26 .new_span(span.clone())
27 .enter(span.clone())
28 .event(expect::event().at_level(Level::ERROR))
29 .exit(span.clone())
30 .drop_span(span)
31 .only()
32 .run_with_handle();
33 with_default(subscriber, || err().ok());
34 handle.assert_finished();
35 }
36
37 #[instrument(err)]
err_early_return() -> Result<u8, TryFromIntError>38 fn err_early_return() -> Result<u8, TryFromIntError> {
39 u8::try_from(1234)?;
40 Ok(5)
41 }
42
43 #[test]
test_early_return()44 fn test_early_return() {
45 let span = expect::span().named("err_early_return");
46 let (subscriber, handle) = subscriber::mock()
47 .new_span(span.clone())
48 .enter(span.clone())
49 .event(expect::event().at_level(Level::ERROR))
50 .exit(span.clone())
51 .drop_span(span)
52 .only()
53 .run_with_handle();
54 with_default(subscriber, || err_early_return().ok());
55 handle.assert_finished();
56 }
57
58 #[instrument(err)]
err_async(polls: usize) -> Result<u8, TryFromIntError>59 async fn err_async(polls: usize) -> Result<u8, TryFromIntError> {
60 let future = PollN::new_ok(polls);
61 tracing::trace!(awaiting = true);
62 future.await.ok();
63 u8::try_from(1234)
64 }
65
66 #[test]
test_async()67 fn test_async() {
68 let span = expect::span().named("err_async");
69 let (subscriber, handle) = subscriber::mock()
70 .new_span(span.clone())
71 .enter(span.clone())
72 .event(
73 expect::event()
74 .with_fields(expect::field("awaiting").with_value(&true))
75 .at_level(Level::TRACE),
76 )
77 .exit(span.clone())
78 .enter(span.clone())
79 .event(expect::event().at_level(Level::ERROR))
80 .exit(span.clone())
81 .enter(span.clone())
82 .exit(span.clone())
83 .drop_span(span)
84 .only()
85 .run_with_handle();
86 with_default(subscriber, || {
87 block_on_future(async { err_async(2).await }).ok();
88 });
89 handle.assert_finished();
90 }
91
92 #[instrument(err)]
err_mut(out: &mut u8) -> Result<(), TryFromIntError>93 fn err_mut(out: &mut u8) -> Result<(), TryFromIntError> {
94 *out = u8::try_from(1234)?;
95 Ok(())
96 }
97
98 #[test]
test_mut()99 fn test_mut() {
100 let span = expect::span().named("err_mut");
101 let (subscriber, handle) = subscriber::mock()
102 .new_span(span.clone())
103 .enter(span.clone())
104 .event(expect::event().at_level(Level::ERROR))
105 .exit(span.clone())
106 .drop_span(span)
107 .only()
108 .run_with_handle();
109 with_default(subscriber, || err_mut(&mut 0).ok());
110 handle.assert_finished();
111 }
112
113 #[instrument(err)]
err_mut_async(polls: usize, out: &mut u8) -> Result<(), TryFromIntError>114 async fn err_mut_async(polls: usize, out: &mut u8) -> Result<(), TryFromIntError> {
115 let future = PollN::new_ok(polls);
116 tracing::trace!(awaiting = true);
117 future.await.ok();
118 *out = u8::try_from(1234)?;
119 Ok(())
120 }
121
122 #[test]
test_mut_async()123 fn test_mut_async() {
124 let span = expect::span().named("err_mut_async");
125 let (subscriber, handle) = subscriber::mock()
126 .new_span(span.clone())
127 .enter(span.clone())
128 .event(
129 expect::event()
130 .with_fields(expect::field("awaiting").with_value(&true))
131 .at_level(Level::TRACE),
132 )
133 .exit(span.clone())
134 .enter(span.clone())
135 .event(expect::event().at_level(Level::ERROR))
136 .exit(span.clone())
137 .enter(span.clone())
138 .exit(span.clone())
139 .drop_span(span)
140 .only()
141 .run_with_handle();
142 with_default(subscriber, || {
143 block_on_future(async { err_mut_async(2, &mut 0).await }).ok();
144 });
145 handle.assert_finished();
146 }
147
148 #[test]
impl_trait_return_type()149 fn impl_trait_return_type() {
150 // Reproduces https://github.com/tokio-rs/tracing/issues/1227
151
152 #[instrument(err)]
153 fn returns_impl_trait(x: usize) -> Result<impl Iterator<Item = usize>, String> {
154 Ok(0..x)
155 }
156
157 let span = expect::span().named("returns_impl_trait");
158
159 let (subscriber, handle) = subscriber::mock()
160 .new_span(
161 span.clone()
162 .with_field(expect::field("x").with_value(&10usize).only()),
163 )
164 .enter(span.clone())
165 .exit(span.clone())
166 .drop_span(span)
167 .only()
168 .run_with_handle();
169
170 with_default(subscriber, || {
171 for _ in returns_impl_trait(10).unwrap() {
172 // nop
173 }
174 });
175
176 handle.assert_finished();
177 }
178
179 #[instrument(err(Debug))]
err_dbg() -> Result<u8, TryFromIntError>180 fn err_dbg() -> Result<u8, TryFromIntError> {
181 u8::try_from(1234)
182 }
183
184 #[test]
test_err_dbg()185 fn test_err_dbg() {
186 let span = expect::span().named("err_dbg");
187 let (subscriber, handle) = subscriber::mock()
188 .new_span(span.clone())
189 .enter(span.clone())
190 .event(
191 expect::event().at_level(Level::ERROR).with_fields(
192 expect::field("error")
193 // use the actual error value that will be emitted, so
194 // that this test doesn't break if the standard library
195 // changes the `fmt::Debug` output from the error type
196 // in the future.
197 .with_value(&tracing::field::debug(u8::try_from(1234).unwrap_err())),
198 ),
199 )
200 .exit(span.clone())
201 .drop_span(span)
202 .only()
203 .run_with_handle();
204 with_default(subscriber, || err_dbg().ok());
205 handle.assert_finished();
206 }
207
208 #[test]
test_err_display_default()209 fn test_err_display_default() {
210 let span = expect::span().named("err");
211 let (subscriber, handle) = subscriber::mock()
212 .new_span(span.clone())
213 .enter(span.clone())
214 .event(
215 expect::event().at_level(Level::ERROR).with_fields(
216 expect::field("error")
217 // by default, errors will be emitted with their display values
218 .with_value(&tracing::field::display(u8::try_from(1234).unwrap_err())),
219 ),
220 )
221 .exit(span.clone())
222 .drop_span(span)
223 .only()
224 .run_with_handle();
225 with_default(subscriber, || err().ok());
226 handle.assert_finished();
227 }
228
229 #[test]
test_err_custom_target()230 fn test_err_custom_target() {
231 let filter: EnvFilter = "my_target=error".parse().expect("filter should parse");
232 let span = expect::span().named("error_span").with_target("my_target");
233
234 let (subscriber, handle) = subscriber::mock()
235 .new_span(span.clone())
236 .enter(span.clone())
237 .event(
238 expect::event()
239 .at_level(Level::ERROR)
240 .with_target("my_target"),
241 )
242 .exit(span.clone())
243 .drop_span(span)
244 .only()
245 .run_with_handle();
246
247 let subscriber = subscriber.with(filter);
248
249 with_default(subscriber, || {
250 let error_span = tracing::error_span!(target: "my_target", "error_span");
251
252 {
253 let _enter = error_span.enter();
254 tracing::error!(target: "my_target", "This should display")
255 }
256 });
257 handle.assert_finished();
258 }
259
260 #[instrument(err(level = "info"))]
err_info() -> Result<u8, TryFromIntError>261 fn err_info() -> Result<u8, TryFromIntError> {
262 u8::try_from(1234)
263 }
264
265 #[test]
test_err_info()266 fn test_err_info() {
267 let span = expect::span().named("err_info");
268 let (subscriber, handle) = subscriber::mock()
269 .new_span(span.clone())
270 .enter(span.clone())
271 .event(expect::event().at_level(Level::INFO))
272 .exit(span.clone())
273 .drop_span(span)
274 .only()
275 .run_with_handle();
276 with_default(subscriber, || err_info().ok());
277 handle.assert_finished();
278 }
279
280 #[instrument(err(Debug, level = "info"))]
err_dbg_info() -> Result<u8, TryFromIntError>281 fn err_dbg_info() -> Result<u8, TryFromIntError> {
282 u8::try_from(1234)
283 }
284
285 #[test]
test_err_dbg_info()286 fn test_err_dbg_info() {
287 let span = expect::span().named("err_dbg_info");
288 let (subscriber, handle) = subscriber::mock()
289 .new_span(span.clone())
290 .enter(span.clone())
291 .event(
292 expect::event().at_level(Level::INFO).with_fields(
293 expect::field("error")
294 // use the actual error value that will be emitted, so
295 // that this test doesn't break if the standard library
296 // changes the `fmt::Debug` output from the error type
297 // in the future.
298 .with_value(&tracing::field::debug(u8::try_from(1234).unwrap_err())),
299 ),
300 )
301 .exit(span.clone())
302 .drop_span(span)
303 .only()
304 .run_with_handle();
305 with_default(subscriber, || err_dbg_info().ok());
306 handle.assert_finished();
307 }
308
309 #[instrument(level = "warn", err(level = "info"))]
err_warn_info() -> Result<u8, TryFromIntError>310 fn err_warn_info() -> Result<u8, TryFromIntError> {
311 u8::try_from(1234)
312 }
313
314 #[test]
test_err_warn_info()315 fn test_err_warn_info() {
316 let span = expect::span().named("err_warn_info").at_level(Level::WARN);
317 let (subscriber, handle) = subscriber::mock()
318 .new_span(span.clone())
319 .enter(span.clone())
320 .event(expect::event().at_level(Level::INFO))
321 .exit(span.clone())
322 .drop_span(span)
323 .only()
324 .run_with_handle();
325 with_default(subscriber, || err_warn_info().ok());
326 handle.assert_finished();
327 }
328