-
Notifications
You must be signed in to change notification settings - Fork 114
[common] Fix NumberFormatException when parsing empty string properties #2372
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
base: main
Are you sure you want to change the base?
[common] Fix NumberFormatException when parsing empty string properties #2372
Conversation
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.
Pull request overview
This PR aims to fix NumberFormatException when parsing empty string properties in VeniceProperties. The changes modify numeric parsing methods (getLong, getInt, getDouble, getSizeInBytes, and getOptionalInt) to handle empty or whitespace-only strings gracefully by either returning default values or throwing descriptive VeniceException instead of NumberFormatException. The PR also includes comprehensive test coverage for these scenarios and unrelated logging level changes in AsyncStoreChangeNotifier.
Changes:
- Modified VeniceProperties numeric parsing methods to check for empty/whitespace-only values before parsing
- Added comprehensive test coverage for empty string handling in all affected methods
- Changed logging level from info to debug in AsyncStoreChangeNotifier (unrelated to main purpose)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 12 comments.
| File | Description |
|---|---|
| internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java | Added empty string checks to getLong, getInt, getDouble, getSizeInBytes, and getOptionalInt methods |
| internal/venice-client-common/src/test/java/com/linkedin/venice/utils/VenicePropertiesTest.java | Added comprehensive test cases for empty string handling in numeric parsing methods |
| internal/venice-common/src/main/java/com/linkedin/venice/meta/AsyncStoreChangeNotifier.java | Changed logging level from info to debug for task registration and execution messages |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-common/src/main/java/com/linkedin/venice/meta/AsyncStoreChangeNotifier.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-common/src/main/java/com/linkedin/venice/meta/AsyncStoreChangeNotifier.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
Modified VeniceProperties numeric parsing methods to handle empty strings gracefully: - getLong/getInt/getDouble/getSizeInBytes methods with default values now return the default when property value is empty or whitespace-only - Methods without default values throw descriptive VeniceException instead of NumberFormatException - getOptionalInt returns Optional.empty() for empty values Added comprehensive TestNG tests covering all modified methods with empty string, whitespace-only, valid, and missing property scenarios.
- Fix whitespace handling bug in numeric parsing methods by trimming values before passing to parse methods (Long.parseLong, Integer.parseInt, Double.parseDouble, convertSizeFromLiteral) - Add comprehensive test coverage for values with leading/trailing whitespace - Revert unrelated logging level changes in AsyncStoreChangeNotifier - Fix SpotBugs CNT_ROUGH_CONSTANT_VALUE violation by changing test value from 3.14 to 3.15 All tests pass and SpotBugs checks pass with 0 violations.
Previously each method called trim() twice: - Once in the isEmpty check: value.trim().isEmpty() - Once for parsing: Long.parseLong(value.trim()) Now each method: 1. Checks for null first 2. Calls trim() once and stores in trimmedValue variable 3. Checks if trimmedValue is empty 4. Parses trimmedValue This reduces string operations and improves performance while maintaining the same behavior.
b5f6211 to
0ef4ee9
Compare
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
internal/venice-client-common/src/main/java/com/linkedin/venice/utils/VeniceProperties.java
Outdated
Show resolved
Hide resolved
| public long getLong(String name, long defaultValue) { | ||
| if (containsKey(name)) { | ||
| return Long.parseLong(get(name)); | ||
| String value = get(name); |
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.
String value = props.get(name);
if (value == null) {
return defaultValue;
}
....
|
Thanks @arjun4084346 & @majisourav99 for the review! |
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (containsKey(name)) { | ||
| return Long.parseLong(get(name)); | ||
| } else { | ||
| if (!containsKey(name)) { |
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.
why double checking containsKey? you already check it in getTrimmedValueOrNull
Addresses review feedback by eliminating redundant containsKey checks in getTrimmedValueOrNull method. Changed from using get() method (which internally checks containsKey) to directly using props.get(), reducing map lookups from 3 to 1 in the happy path. Also deferred containsKey checks in getLong/getInt/ getDouble/getSizeInBytes methods to only execute when distinguishing between missing keys and empty values.
| } else { | ||
| throw new UndefinedPropertyException(name); | ||
| String trimmedValue = getTrimmedValueOrNull(name); | ||
| if (trimmedValue == null) { |
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.
sorry for minor comments; but i think L365-L368 can also go inside method getTrimmedValueOrNull and it can be renamed like getTrimmedNonEmptyValueOrThrowException
|
From Claude Code PR Review ⏺ Pull Request Review: #2372 Title: [common] Fix NumberFormatException when parsing empty string properties Summary This PR fixes a bug where empty string property values cause NumberFormatException when parsing numeric values in VeniceProperties.java. The fix centralizes empty/null handling across all numeric getter methods. Changes Overview Files Modified: 3 files (+61/-49 lines)
What I Like ✓
Potential Concerns / Questions
Code Quality: 8.5/10 This is a solid defensive programming fix that improves robustness. The refactoring reduces code duplication and makes the codebase more maintainable. The main consideration is ensuring this behavior change doesn't break existing configurations. Recommendation: ✅ Approve with minor consideration for communication about the behavior change in release notes. |
[common] Fix NumberFormatException when parsing empty string properties
Modified VeniceProperties numeric parsing methods to handle empty strings gracefully: -
getLong/getInt/getDouble/getSizeInBytes methods with default values now return the default
when property value is empty or whitespace-only - Methods without default values throw
descriptive VeniceException instead of NumberFormatException - getOptionalInt returns
Optional.empty() for empty values
Code changes
Concurrency-Specific Checks
Both reviewer and PR author to verify
synchronized,RWLock) are used where needed.ConcurrentHashMap,CopyOnWriteArrayList).How was this PR tested?
Does this PR introduce any user-facing or breaking changes?