Skip to content
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: replace deprecated API in chrono 0.4.35 for converting to time #367

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

bconn98
Copy link
Collaborator

@bconn98 bconn98 commented Apr 4, 2024

Replace deprecated time conversion API from chrono crate.

Deprecation occured in v0.4.35.
Work performed by @Dirreke
Separated out by @bconn98
Resolves #366

@codecov-commenter
Copy link

codecov-commenter commented Apr 4, 2024

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 88.88889% with 3 lines in your changes missing coverage. Please review.

Project coverage is 63.88%. Comparing base (8ab1b34) to head (9acd373).
Report is 2 commits behind head on main.

Files Patch % Lines
...ppend/rolling_file/policy/compound/trigger/time.rs 88.88% 3 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #367      +/-   ##
==========================================
+ Coverage   63.39%   63.88%   +0.49%     
==========================================
  Files          24       25       +1     
  Lines        1557     1581      +24     
==========================================
+ Hits          987     1010      +23     
- Misses        570      571       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Dirreke
Copy link
Contributor

Dirreke commented Apr 4, 2024

and we can add this test

    #[test]
    fn trigger_large_interval() {
        let interval = TimeTriggerInterval::Second(i64::MAX);
        let file = tempfile::tempdir().unwrap();
        let logfile = LogFile {
            writer: &mut None,
            path: file.path(),
            len: 0,
        };
        let config = TimeTriggerConfig {
            interval,
            ..Default::default()
        };

        let trigger = TimeTrigger::new(config);
        let error = trigger.trigger(&logfile).unwrap_err();
        let box_dyn = Box::<dyn StdError>::from(error);
        assert_eq!(
            format!("The integer value {:?} for the specified time trigger interval is too large, it must be less than 9,223,372,036,854,775,807 seconds.", interval),
            box_dyn.to_string()
        );
    }

@bconn98
Copy link
Collaborator Author

bconn98 commented Apr 4, 2024

and we can add this test

@Dirreke Doesn't look like it's doable without some of your refactor. Based on needing to unwrap the error in the new method vs unwrapping in the trigger. If you see another option let me know. I messed around with catch_unwind but without a concrete error type that wasn't working for me.

Copy link
Owner

@estk estk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, added a few comments.

Basically .unwrap() is ok if there is some explanation as to why it will never happen. (I usually add a comment on the proceeding line.)

For example unwrap is fine if you are passing literals in that you know to be fine. But as soon as you're taking user input we probably need to start handling errors.

Also, just want to note that they really arent your unwraps, just, while were in here we should do the "correct" thing.

src/append/rolling_file/policy/compound/trigger/time.rs Outdated Show resolved Hide resolved
src/append/rolling_file/policy/compound/trigger/time.rs Outdated Show resolved Hide resolved
.and_local_timezone(Local)
.unwrap()
};

#[cfg(not(test))]
let current = Local::now();
let next_time = TimeTrigger::get_next_time(current, config.interval, config.modulate);
let next_time =
TimeTrigger::get_next_time(current, config.interval, config.modulate).unwrap();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to remove this unwrap and handle the error

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a match which panics on error. This can be handled more gracefully with changes from #347 which changes where get_next_time is called to a method that returns a result.

Copy link
Collaborator Author

@bconn98 bconn98 Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swapped to unwrap_or with a 1 second increment

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated new to return a Result and passed the result up

src/append/rolling_file/policy/compound/trigger/time.rs Outdated Show resolved Hide resolved
@bconn98
Copy link
Collaborator Author

bconn98 commented Jul 10, 2024

@estk it looks like Codecov wiped out your access token. Can you try and fix that?

@bconn98 bconn98 force-pushed the 366_chrono_bump_fix_deprecations branch from 4263205 to 303d009 Compare July 10, 2024 01:20
src/append/rolling_file/policy/compound/trigger/time.rs Outdated Show resolved Hide resolved
Comment on lines 75 to 88
#[derive(Debug, Error)]
enum TimeTrigerIntervalError {
#[error("The 'Seconds' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Second(TimeTriggerInterval),
#[error("The 'Minutes' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Minute(TimeTriggerInterval),
#[error("The 'Hours' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Hour(TimeTriggerInterval),
#[error("The 'Days' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Day(TimeTriggerInterval),
#[error("The 'Weeks' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Week(TimeTriggerInterval),
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think it's necessary either. For users, all these parameters are from the item interval, so just "the interval value....." is enough imo.

Copy link
Owner

@estk estk Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment that was something to the effect of "we should add context to errors". I obviously didnt add enough context, sorry. My point was this: if a user has a huge config with many intervals we need to set up the error handling such that when surfaced to the user, they know which interval was out of bounds.

So we need to:

  1. Simply add a position discriminant to this error, roughly:
#[derive(Debug, Error)]
enum TimeTriggerIntervalError {
    #[error("The '{}' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{0:?}'")]
    OutOfBounds(Position, TimeTriggerInterval)
}
  1. Ensure that in the caller that TimeTriggerIntervalError is handled and the name of the appender containing it is provided to the user.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can access the name anywhere close to the triggers. They're owned in the config module but are not available anywhere within the append module that I can find

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I've been staring at this and tried a slew of different things, none of which I think get close to what you're asking for here. I think I need some assistance.

Like I mentioned we don't have access to the appender name, and I'm not really sure what you mean by a Position discriminant. The Error already reports the type of the interval (Seconds, Minutes, Hours, etc.) and I'm not sure what else we can add of value to the user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think it's necessary to include the appender name. The incorrect interval numbers is enougn to assist users to locate the configuration. Even if they have duplicate incorrect number, they need fix them all because all these numbers will be incorrect for interval

@Dirreke
Copy link
Contributor

Dirreke commented Jul 10, 2024

Thanks for the code! ♥️♥️

@estk
Copy link
Owner

estk commented Jul 10, 2024

Just wanted to add some more context here. It makes sense to use failable versions of for example Duration::weeks(), the only thing is it needs to be accompanied by an error handling strategy that gracefully presents that error and provides the context for the user to fix that error.

Previously by using the panicking version of these methods the error handling is easy, it just unwinds and gives the user (optionally) a stack trace to go find what happened. Aspirationally we would be able to use the failable methods and direct the user to the data that caused the issue instead of the code that caught the issue. (This is what would be possible in your current approach.)

However, if we're going to go thru the trouble of preventing a panic, we need to ensure the usability and debuggability is at least as good as it was when we panicked. As to how we do this... idk, but I'm certain we should alert the user that their input was incorrect instead of simply selecting some arbitrary default. IMO, without holistically rethinking our approach to presenting errors to users it will be difficult to present errors well without panicking.

Comment on lines 75 to 88
#[derive(Debug, Error)]
enum TimeTrigerIntervalError {
#[error("The 'Seconds' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Second(TimeTriggerInterval),
#[error("The 'Minutes' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Minute(TimeTriggerInterval),
#[error("The 'Hours' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Hour(TimeTriggerInterval),
#[error("The 'Days' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Day(TimeTriggerInterval),
#[error("The 'Weeks' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'")]
Week(TimeTriggerInterval),
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides, I remember now why I put a specific number here before. The max value of these is not i64::MAX. They should be within i64::MAX after they convert to milliseconds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action worthy?

src/append/rolling_file/policy/compound/trigger/time.rs Outdated Show resolved Hide resolved
@bconn98
Copy link
Collaborator Author

bconn98 commented Jul 10, 2024

FWIW the get_next_time error would be one that we generate, so I think we can/do/will when I fix the IntervalError provide some data to the user.

Bigger picture, we can setup a milestone + branch to start working towards a 2.0 version that includes the API change for multiple rollers and an informative but not panicking solution.

@bconn98 bconn98 requested review from estk and Dirreke July 13, 2024 01:56
@bconn98
Copy link
Collaborator Author

bconn98 commented Jul 13, 2024

Closes #367

@SL-RU
Copy link

SL-RU commented Aug 11, 2024

@estk can you review please?

@Daniel599
Copy link

Hi, any update regarding this PR?
Looking forward for the support of date in log format.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Resolve Deprecated Chrono API
6 participants