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