-
Notifications
You must be signed in to change notification settings - Fork 542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix format panic problem #614
Conversation
format: change the behaviour of format::format_inner(), disable it from throwing fmt::Error if item is in wrong format, or has an argument missing problem. Doing this will prevent program from panic if trying to format an instance, say `Date`, with an inproper format string.
This unfortunately causes errors to become silent. A better solution would be to introduce a |
src/datetime.rs
Outdated
// pass a wrong format | ||
assert_eq!( | ||
format!("{}", naive_date.format("%Y %{whatever} %d")), | ||
String::from("2000 whatever} 12") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If invalid, I would imagine this would simply produce "%{whatever}", not "whatever}"
If invalid, I would imagine this would simply produce "%{whatever}", not
"whatever}"
That sounds reasonable. I'll work on it.
By the way, I think the idea to introduce a new method that returns
`Result<DelayedFormat, FormatError>`, which is mentioned before, is also an
attractive solution to this problem. I can also give a try on it.
|
Maybe create another function that returns a Result? |
I roughly created a |
StrftimeItems: Modify the implementation of Iterator for StrftimeItems. Item::Error is changed to be Item::Error(&'a str) for more flexible usages. Others: Add some tests for NaiveDateTime, NaiveDate and NaiveTime.
Any update on this PR? |
What's the path here? Is there some outer API here that's not propagating the error from the inner API, but panicking instead? |
Yes, it's the panic problem. The original |
Yeah, I don't think this is an improvement. If we're going to stop panicking, we should explicitly signal an error some other way. |
Just to add another option here, and I recognize this isn't super user friendly or discoverable, (we can potentially fix that with a few helper functions or more docs) but the potentially invalid user input problem can be solved in the currently released If you want to just check whether the format string is valid or not, using use chrono::{Utc, format::{Item, strftime::StrftimeItems}}; // 0.4.19
use std::fmt::Write;
const BAD_FMT_STR: &str = "%Y-%m-%";
const GOOD_FMT_STR: &str = "%Y-%m-%d";
fn main() {
assert!(StrftimeItems::new(BAD_FMT_STR).any(|i| matches!(i, Item::Error)));
assert!(StrftimeItems::new(GOOD_FMT_STR).all(|i| !matches!(i, Item::Error)));
let mut out = String::new();
assert!(write!(&mut out, "{}", Utc::now().date().naive_local().format(GOOD_FMT_STR)).is_ok());
assert!(write!(&mut out, "{}", Utc::now().date().naive_local().format(BAD_FMT_STR)).is_err());
} |
I've added a draft PR which shows some options here: #735 |
Add some modification to
format::inner_format()
, which will prevent the program from panic when an inproper format string is provided. This is the problem mentioned in issue #575 .The new strategy I'm using is to skip those inproper format substrings. You can find some of the examples in the test I add. I think this strategy is better than directly panic, especially when handling user input strings. Skipping the wrong parts will also indicate an invalid format string, and giving the programmer an opportunity to fix the problem while running, instead of panic and terminating the program.