fix: guard DurationParamType against OverflowError on large values#722
Conversation
…alues Catch OverflowError from timedelta(seconds=...) in all three input paths (integer type, string-parsed integer, pytimeparse2 result) and raise click.BadParameter with a user-friendly message instead of letting the OverflowError propagate uncaught. Extract string parsing into _parse_string to keep convert complexity within the C901 threshold. Generated-By: Forge/20260601_094654_364912_325fe880
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughExtracts DurationParamType string parsing into _parse_string (int seconds → pytimeparse2 → TypeAdapter(timedelta)) with OverflowError handling; convert() delegates str/int to it, retains timedelta passthrough and minimum-duration validation, and adds tests for oversized inputs causing click.BadParameter. ChangesDuration Parsing Refactor with Overflow Protection
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ty type checker cannot infer that self.fail() is NoReturn, so it reports an implicit None return. Re-raise the caught exception after self.fail() to make the control flow explicit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- F001: catch OverflowError separately from (ValueError, TypeError) in the parse_duration path so overflowing pytimeparse2 results produce the correct "exceeds the maximum allowed duration" message instead of falling through to the generic "is not a valid duration" error - F002: remove unreachable `raise exc` after self.fail() (which is NoReturn) and drop the now-unused `as exc` binding to satisfy ruff F841 - F003: merge the isinstance(value, int) branch in convert() into the str path by converting int to str before calling _parse_string, eliminating duplicated overflow guard logic Add test for pytimeparse2-triggered overflow to cover the F001 fix path. Generated-By: Forge/20260603_092845_714320_2a6250dc
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@python/packages/jumpstarter-cli/jumpstarter_cli/common.py`:
- Around line 40-67: The _parse_string function can implicitly return None
because mypy/ty doesn't treat self.fail(...) as non-returning; update
_parse_string to make all error paths explicitly non-returning by adding an
explicit raise after each self.fail call (for example: self.fail(...); raise
RuntimeError from None) so the type-checker knows these branches never return;
target the self.fail calls inside _parse_string (the ones after
int/OverflowError, after parse_duration/OverflowError, and in the final except
handling TypeAdapter.validate_python) and keep the rest of the logic
(parse_duration, TypeAdapter(timedelta).validate_python) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6c43dfd8-294b-4648-8e06-aabe8229c2ac
📒 Files selected for processing (2)
python/packages/jumpstarter-cli/jumpstarter_cli/common.pypython/packages/jumpstarter-cli/jumpstarter_cli/common_test.py
ty cannot statically verify that click's self.fail() is NoReturn, causing an invalid-return-type error on _parse_string(). Adding unreachable raise statements after each self.fail() call makes the non-returning control flow explicit for the type checker. Generated-By: Forge/20260603_100418_749257_f488b03d Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Mohamad Abo Ras <maboras@redhat.com>
…sistency The _parse_string method consistently adds `raise` after every self.fail() call to satisfy the ty type-checker (which cannot verify that self.fail is NoReturn). The convert() method was missing this pattern in two locations: the else branch for unsupported types and the minimum duration check. This could cause ty to report possibly-unbound diagnostics for the `td` variable. Generated-By: Forge/20260604_121105_16706_dd080c63
Add a test verifying that a value at the upper boundary of timedelta.max (999999999 days = 86399999913600 seconds) succeeds, complementing the existing overflow tests that use clearly-overflowing values. This documents the exact threshold and would catch any off-by-one errors in boundary handling. Generated-By: Forge/20260604_121105_16706_dd080c63
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@python/packages/jumpstarter-cli/jumpstarter_cli/common_test.py`:
- Around line 111-114: The test test_value_at_timedelta_max_seconds_succeeds
uses the wrong boundary value: replace the input string "86399999913600" passed
to DURATION.convert with the true max whole-second boundary "86399999999999" and
update the assertion to expect the corresponding maximal timedelta of 999999999
days and 23:59:59 (e.g., timedelta(days=999999999, seconds=86399) or equivalent)
so the test validates the immediate pre-overflow edge.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f7292149-263a-4008-8049-eb3388642e26
📒 Files selected for processing (2)
python/packages/jumpstarter-cli/jumpstarter_cli/common.pypython/packages/jumpstarter-cli/jumpstarter_cli/common_test.py
🚧 Files skipped from review as they are similar to previous changes (1)
- python/packages/jumpstarter-cli/jumpstarter_cli/common.py
Use 86399999999999 (999999999d 23h 59m 59s) instead of 86399999913600 to test the true maximum seconds value that fits in timedelta.max. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
OverflowErrorcrash inDurationParamType.convert()when extremely large integer values (e.g.86400000000000) are passed, which causetimedelta(seconds=...)to overflowOverflowErrorin both the integer and string-integer parsing paths and converts it to a user-friendlyclick.BadParametererror_parse_string()for clarity and addsOverflowErrorto thepytimeparse2exception handlingCloses #717
Test plan
test_large_string_integer_raises_bad_parameter_not_overflow-- verifies string"86400000000000"raisesBadParameternotOverflowErrortest_large_integer_raises_bad_parameter_not_overflow-- verifies int86400000000000raisesBadParameternotOverflowErrortest_large_negative_string_raises_bad_parameter_not_overflow-- verifies string"-86400000000000"raisesBadParameternotOverflowErrorDurationParamTypetests continue to pass🤖 Generated with Claude Code