@@ -73,17 +73,9 @@ impl Default for TimeTriggerInterval {
73
73
}
74
74
75
75
#[ derive( Debug , Error ) ]
76
- enum TimeTrigerIntervalError {
77
- #[ error( "The 'Seconds' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'" ) ]
78
- Second ( TimeTriggerInterval ) ,
79
- #[ error( "The 'Minutes' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'" ) ]
80
- Minute ( TimeTriggerInterval ) ,
81
- #[ error( "The 'Hours' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'" ) ]
82
- Hour ( TimeTriggerInterval ) ,
83
- #[ error( "The 'Days' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'" ) ]
84
- Day ( TimeTriggerInterval ) ,
85
- #[ error( "The 'Weeks' time trigger interval value is out of bounds, ensure it fits within an i64: : '{0:?}'" ) ]
86
- Week ( TimeTriggerInterval ) ,
76
+ enum TimeTriggerIntervalError {
77
+ #[ error( "The '{0}' value specified as a time trigger is out of bounds, ensure it fits within an i64: : '{1:?}'" ) ]
78
+ OutOfBounds ( String , TimeTriggerInterval ) ,
87
79
}
88
80
89
81
#[ cfg( feature = "config_parsing" ) ]
@@ -188,7 +180,7 @@ impl<'de> serde::Deserialize<'de> for TimeTriggerInterval {
188
180
impl TimeTrigger {
189
181
/// Returns a new trigger which rolls the log once it has passed the
190
182
/// specified time.
191
- pub fn new ( config : TimeTriggerConfig ) -> TimeTrigger {
183
+ pub fn new ( config : TimeTriggerConfig ) -> anyhow :: Result < TimeTrigger > {
192
184
#[ cfg( test) ]
193
185
let current = {
194
186
let now: std:: time:: Duration = SystemTime :: now ( )
@@ -203,9 +195,8 @@ impl TimeTrigger {
203
195
204
196
#[ cfg( not( test) ) ]
205
197
let current = Local :: now ( ) ;
206
- // In the case where bad user input results in an invalid next time, provide a valid time.
207
- let next_time = TimeTrigger :: get_next_time ( current, config. interval , config. modulate )
208
- . unwrap_or ( current + Duration :: try_seconds ( 1_i64 ) . unwrap ( ) ) ;
198
+ // TODO: Design an implement error handling at a project level scope instead of panic
199
+ let next_time = TimeTrigger :: get_next_time ( current, config. interval , config. modulate ) ?;
209
200
let next_roll_time = if config. max_random_delay > 0 {
210
201
let random_delay = rand:: thread_rng ( ) . gen_range ( 0 ..config. max_random_delay ) ;
211
202
// This is a valid unwrap because chrono::Duration::try_milliseconds accepts an i64
@@ -220,17 +211,17 @@ impl TimeTrigger {
220
211
next_time
221
212
} ;
222
213
223
- TimeTrigger {
214
+ Ok ( TimeTrigger {
224
215
config,
225
216
next_roll_time : RwLock :: new ( next_roll_time) ,
226
- }
217
+ } )
227
218
}
228
219
229
220
fn get_next_time (
230
221
current : DateTime < Local > ,
231
222
interval : TimeTriggerInterval ,
232
223
modulate : bool ,
233
- ) -> Result < DateTime < Local > , TimeTrigerIntervalError > {
224
+ ) -> Result < DateTime < Local > , TimeTriggerIntervalError > {
234
225
let year = current. year ( ) ;
235
226
if let TimeTriggerInterval :: Year ( n) = interval {
236
227
let n = n as i32 ;
@@ -259,18 +250,21 @@ impl TimeTrigger {
259
250
let weekday = current. weekday ( ) . num_days_from_monday ( ) as i64 ; // Monday is the first day of the week
260
251
let time = Local . with_ymd_and_hms ( year, month, day, 0 , 0 , 0 ) . unwrap ( ) ;
261
252
let increment = if modulate { n - week0 % n } else { n } ;
262
- let dur = Duration :: try_weeks ( increment)
263
- . ok_or ( TimeTrigerIntervalError :: Week ( interval) ) ?
264
- - Duration :: try_days ( weekday) . ok_or ( TimeTrigerIntervalError :: Day ( interval) ) ?;
253
+ let dur = Duration :: try_weeks ( increment) . ok_or (
254
+ TimeTriggerIntervalError :: OutOfBounds ( "Weeks" . to_owned ( ) , interval) ,
255
+ ) ? - Duration :: try_days ( weekday) . ok_or (
256
+ TimeTriggerIntervalError :: OutOfBounds ( "Days" . to_owned ( ) , interval) ,
257
+ ) ?;
265
258
return Ok ( time + dur) ;
266
259
}
267
260
268
261
if let TimeTriggerInterval :: Day ( n) = interval {
269
262
let ordinal0 = current. ordinal0 ( ) as i64 ;
270
263
let time = Local . with_ymd_and_hms ( year, month, day, 0 , 0 , 0 ) . unwrap ( ) ;
271
264
let increment = if modulate { n - ordinal0 % n } else { n } ;
272
- let dur =
273
- Duration :: try_days ( increment) . ok_or ( TimeTrigerIntervalError :: Day ( interval) ) ?;
265
+ let dur = Duration :: try_days ( increment) . ok_or (
266
+ TimeTriggerIntervalError :: OutOfBounds ( "Days" . to_owned ( ) , interval) ,
267
+ ) ?;
274
268
return Ok ( time + dur) ;
275
269
}
276
270
@@ -280,8 +274,9 @@ impl TimeTrigger {
280
274
. with_ymd_and_hms ( year, month, day, hour, 0 , 0 )
281
275
. unwrap ( ) ;
282
276
let increment = if modulate { n - ( hour as i64 ) % n } else { n } ;
283
- let dur =
284
- Duration :: try_hours ( increment) . ok_or ( TimeTrigerIntervalError :: Hour ( interval) ) ?;
277
+ let dur = Duration :: try_hours ( increment) . ok_or (
278
+ TimeTriggerIntervalError :: OutOfBounds ( "Hours" . to_owned ( ) , interval) ,
279
+ ) ?;
285
280
return Ok ( time + dur) ;
286
281
}
287
282
@@ -291,8 +286,9 @@ impl TimeTrigger {
291
286
. with_ymd_and_hms ( year, month, day, hour, min, 0 )
292
287
. unwrap ( ) ;
293
288
let increment = if modulate { n - ( min as i64 ) % n } else { n } ;
294
- let dur = Duration :: try_minutes ( increment)
295
- . ok_or ( TimeTrigerIntervalError :: Minute ( interval) ) ?;
289
+ let dur = Duration :: try_minutes ( increment) . ok_or (
290
+ TimeTriggerIntervalError :: OutOfBounds ( "Minutes" . to_owned ( ) , interval) ,
291
+ ) ?;
296
292
return Ok ( time + dur) ;
297
293
}
298
294
@@ -302,8 +298,9 @@ impl TimeTrigger {
302
298
. with_ymd_and_hms ( year, month, day, hour, min, sec)
303
299
. unwrap ( ) ;
304
300
let increment = if modulate { n - ( sec as i64 ) % n } else { n } ;
305
- let dur = Duration :: try_seconds ( increment)
306
- . ok_or ( TimeTrigerIntervalError :: Second ( interval) ) ?;
301
+ let dur = Duration :: try_seconds ( increment) . ok_or (
302
+ TimeTriggerIntervalError :: OutOfBounds ( "Seconds" . to_owned ( ) , interval) ,
303
+ ) ?;
307
304
return Ok ( time + dur) ;
308
305
}
309
306
panic ! ( "Should not reach here!" ) ;
@@ -329,7 +326,7 @@ impl Trigger for TimeTrigger {
329
326
let mut next_roll_time = self . next_roll_time . write ( ) . unwrap ( ) ;
330
327
let is_trigger = current >= * next_roll_time;
331
328
if is_trigger {
332
- let tmp = TimeTrigger :: new ( self . config ) ;
329
+ let tmp = TimeTrigger :: new ( self . config ) ? ;
333
330
let time_new = tmp. next_roll_time . read ( ) . unwrap ( ) ;
334
331
* next_roll_time = * time_new;
335
332
}
@@ -368,7 +365,7 @@ impl Deserialize for TimeTriggerDeserializer {
368
365
config : TimeTriggerConfig ,
369
366
_: & Deserializers ,
370
367
) -> anyhow:: Result < Box < dyn Trigger > > {
371
- Ok ( Box :: new ( TimeTrigger :: new ( config) ) )
368
+ Ok ( Box :: new ( TimeTrigger :: new ( config) ? ) )
372
369
}
373
370
}
374
371
@@ -396,7 +393,7 @@ mod test {
396
393
max_random_delay : 0 ,
397
394
} ;
398
395
399
- let trigger = TimeTrigger :: new ( config) ;
396
+ let trigger = TimeTrigger :: new ( config) . unwrap ( ) ;
400
397
401
398
MockClock :: advance_system_time ( Duration :: from_millis ( millis / 2 ) ) ;
402
399
let result1 = trigger. trigger ( & logfile) . unwrap ( ) ;
@@ -526,6 +523,18 @@ mod test {
526
523
max_random_delay : 0 ,
527
524
} ;
528
525
let trigger = TimeTrigger :: new ( config) ;
529
- assert ! ( trigger. is_pre_process( ) ) ;
526
+ assert ! ( trigger. unwrap( ) . is_pre_process( ) ) ;
527
+ }
528
+
529
+ #[ test]
530
+ fn test_err ( ) {
531
+ let config = TimeTriggerConfig {
532
+ interval : TimeTriggerInterval :: Day ( i64:: MAX ) ,
533
+ modulate : false ,
534
+ max_random_delay : 0 ,
535
+ } ;
536
+
537
+ let trigger = TimeTrigger :: new ( config) ;
538
+ assert ! ( trigger. is_err( ) ) ;
530
539
}
531
540
}
0 commit comments