chrono
chrono copied to clipboard
DelayedFormat: Panic in rendering
This code:
use chrono::NaiveDateTime;
fn main() {
let naive_date_time =
NaiveDateTime::parse_from_str("2024-06-07T00:00:00+09:00", "%Y-%m-%dT%H:%M:%S%:z").unwrap();
dbg!(&naive_date_time);
let format = "%FT%T%:z";
let delayed_format = naive_date_time.format(format);
dbg!(&delayed_format);
println!("{}", delayed_format);
}
Results in these debug outputs:
[src/main.rs:6:5] &naive_date_time = 2024-06-07T00:00:00
[src/main.rs:10:5] &delayed_format = DelayedFormat {
date: Some(
2024-06-07,
),
time: Some(
00:00:00,
),
off: None,
items: StrftimeItems {
remainder: "%FT%T%:z",
queue: [],
},
locale: Locale,
}
which seem to be all valid.
Then panics when trying to render the formatting to string:
thread 'main' panicked at library/std/src/io/stdio.rs:1088:9:
failed printing to stdout: formatter error
stack backtrace:
0: 0x100245030 - std::backtrace_rs::backtrace::libunwind::trace::h6de1cbf3f672a4f8
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/../../backtrace/src/backtrace/libunwind.rs:105:5
1: 0x100245030 - std::backtrace_rs::backtrace::trace_unsynchronized::hd0de2d5ef13b6f4d
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x100245030 - std::sys_common::backtrace::_print_fmt::h2a33510d9b3bb866
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:68:5
3: 0x100245030 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h01b2beffade888b2
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:44:22
4: 0x10025a610 - core::fmt::rt::Argument::fmt::h5ddc0f22b2928899
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/fmt/rt.rs:142:9
5: 0x10025a610 - core::fmt::write::hbadb443a71b75f23
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/fmt/mod.rs:1153:17
6: 0x100243338 - std::io::Write::write_fmt::hc09d7755e3ead5f0
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/io/mod.rs:1843:15
7: 0x100244e88 - std::sys_common::backtrace::_print::h3cd1786cbb1caf0f
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:47:5
8: 0x100244e88 - std::sys_common::backtrace::print::h28349e5c25acbac7
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:34:9
9: 0x100246248 - std::panicking::default_hook::{{closure}}::hd24b6196784d991e
10: 0x100245f2c - std::panicking::default_hook::hfcec80a2720c8c73
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:292:9
11: 0x100246b3c - std::panicking::rust_panic_with_hook::h84760468187ddc85
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:779:13
12: 0x100246528 - std::panicking::begin_panic_handler::{{closure}}::he666a5eb600a7203
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:657:13
13: 0x1002454b4 - std::sys_common::backtrace::__rust_end_short_backtrace::h592f44d2bf9f843f
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:171:18
14: 0x1002462a0 - rust_begin_unwind
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:645:5
15: 0x10026076c - core::panicking::panic_fmt::h98bbf7bdf4994454
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/panicking.rs:72:14
16: 0x100242bc8 - std::io::stdio::print_to::h4b6256ffd4fd0562
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/io/stdio.rs:1088:9
17: 0x100242bc8 - std::io::stdio::_print::hd9ffb3f73dfcc2b3
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/io/stdio.rs:1164:5
18: 0x100208f14 - chrono_panic::main::h9483e9876fb5629c
at /Users/behnam/code/misc/chrono-panic/src/main.rs:12:5
19: 0x10020a208 - core::ops::function::FnOnce::call_once::h5ae5a043b13877fa
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/ops/function.rs:250:5
20: 0x10020a3ec - std::sys_common::backtrace::__rust_begin_short_backtrace::he612149a7c555640
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/sys_common/backtrace.rs:155:18
21: 0x10020860c - std::rt::lang_start::{{closure}}::h2a0bca82aa73c2fc
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:166:18
22: 0x100241084 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::heaba8a29e0324069
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/ops/function.rs:284:13
23: 0x100241084 - std::panicking::try::do_call::h6e5fac4f4884d97b
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:552:40
24: 0x100241084 - std::panicking::try::h2b98e2f3cf76cd78
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:516:19
25: 0x100241084 - std::panic::catch_unwind::hba9c97319335c08b
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panic.rs:146:14
26: 0x100241084 - std::rt::lang_start_internal::{{closure}}::h18efdcfb68f002e8
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:148:48
27: 0x100241084 - std::panicking::try::do_call::ha793e16770aada4d
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:552:40
28: 0x100241084 - std::panicking::try::h8aa812e3e1310d12
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:516:19
29: 0x100241084 - std::panic::catch_unwind::h38c4879f2623185e
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panic.rs:146:14
30: 0x100241084 - std::rt::lang_start_internal::h39923ab4c3913741
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:148:20
31: 0x1002085d8 - std::rt::lang_start::h386185eb75fa91dd
at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:165:17
32: 0x100208f6c - _main
I can repro this on both default features, as well as { version = "0.4.38", default-features = false, features = ["std"] }.
You have a time zone specifier (%z) combined with a type (NaiveDateTime) that does not support time zones -- I think this is the problem. Unfortunately the format() method was not defined as fallible, so we don't have a good way of yielding an error -- although maybe we should deprecate format() in favor of try_format() in 0.4?
We have been working on making this better on the 0.5 branch, including hopefully making this sort of thing fail to compile.
I see. My assumption was that if a formatting option is not supported, either DelayedFormat won't be instantiated, or the formatting option would be ignored (becoming a literal string).
Yeah, I would love to see a fallible API for this! Thanks!
Now that you mentioned the behavior, I understand the intention of the last paragraph of the doc: https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDateTime.html#method.format . I think it might be useful to make these docs more explicit about the "fails" being a thread panic, either by updating the wording of the sentence, or maybe even adding a "Panics" section to the doc similar to the rust-lang docs (example)
Anyways, leaving it for you to decide if any it's useful to keep this issue open. Thanks again for the prompt response!
I think it might be useful to make these docs more explicit about the "fails" being a thread panic, either by updating the wording of the sentence, or maybe even adding a "Panics" section to the doc similar to the rust-lang docs (example)
Would you be able to make a PR with a proposal? Would be much appreciated!
Okay, submitted https://github.com/chronotope/chrono/pull/1590
Unfortunately the
format()method was not defined as fallible, so we don't have a good way of yielding an error -- although maybe we should deprecateformat()in favor oftry_format()in 0.4?
It would be amazing if a failable try_format API were made available.
Especially when chrono is used in other libraries (like polars in our case) it is quite annoying to get an unexpected panic in third party code. While this was a configuration error on our part, it was not easy to figure out what went wrong, as Rust does not provide an appropriate panic message either.