fix(spark): improve error message when precombine field value is null#18061
fix(spark): improve error message when precombine field value is null#18061prashantwason wants to merge 6 commits intoapache:masterfrom
Conversation
| throw new IllegalArgumentException( | ||
| s"Precombine/ordering field '$field' has null value for record key '${hoodieKey.getRecordKey}'. " + | ||
| s"Please ensure all records have non-null values for the precombine field, " + | ||
| s"or use a payload class that doesn't require ordering (e.g., OverwriteWithLatestAvroPayload).") |
There was a problem hiding this comment.
In previous versions of hudi, its common for users to configure precombine field even w/ OverwriteWithLatestAvroPayload. But in later versions, we fully relaxed the constraint and its totally fine to not have precombine field configured or have precombine configured, but some records could have null values, assuming the payload is OverwriteWithLatestAvroPayload or merge mode is RecordMergeMode.COMMIT_TIME_ORDERING
So, if we were to throw exception here, atleast we need to check the payload and merge mode and then throw exception accordingly.
For eg, incase of OverwriteWithLatestAvroPayload or RecordMergeMode.COMMIT_TIME_ORDERING, we don't wanna throw exception
There was a problem hiding this comment.
Thanks for the feedback @nsivabalan, you're correct.
I'll update the PR to check the merge mode and payload class before throwing the exception. The null check should only throw when ordering is actually required, specifically:
- Skip the exception for
RecordMergeMode.COMMIT_TIME_ORDERING - Skip the exception for
OverwriteWithLatestAvroPayload
For these cases, I'll use OrderingValues.getDefault() as a fallback instead of throwing, which aligns with how OverwriteWithLatestAvroPayload handles missing ordering values in its constructor.
Will push an updated commit shortly.
|
@hudi-bot run azure |
|
Updated error message to use "Ordering field" instead of "Precombine/ordering field" since the precombine notion is deprecated since version 1.1. @hudi-bot run azure |
| field => HoodieAvroUtils.getNestedFieldVal(avroRec, field, false, | ||
| consistentLogicalTimestampEnabled).asInstanceOf[Comparable[_]])) | ||
| field => { | ||
| val fieldVal = HoodieAvroUtils.getNestedFieldVal(avroRec, field, false, |
There was a problem hiding this comment.
this is becoming too fat.
can we move this to a private method.
There was a problem hiding this comment.
should we also add similar logic to spark record type as well?
…l during payload creation When records have null values in the precombine field, Hudi jobs fail with a cryptic error message "Ordering value is null for record" that makes it difficult for users to diagnose the root cause. This change adds explicit null-checking with a clear, actionable error message before attempting payload creation. The new error message: - Identifies the specific precombine/ordering field that has a null value - Provides the record key to help locate the problematic record - Suggests remediation options (fix data or use OverwriteWithLatestAvroPayload) Closes apache#18060 Co-Authored-By: Claude (claude-opus-4-5) <noreply@anthropic.com>
…dataWriterTableVersionSix Added unit tests to verify the behavior of shouldInitializeFromFilesystem() method which allows metadata table bootstrap when pending commits are being rolled back: - Test initialization allowed when no pending data instants - Test initialization allowed when only pending instant is current inflight - Test initialization blocked when blocking instants have no rollbacks - Test initialization allowed when all blocking instants have pending rollbacks - Test initialization blocked when only some blocking instants have rollbacks - Test mixed scenario with current inflight and rollbacks for other instants - Test that completed rollbacks do not count as pending rollbacks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…erwriteWithLatestAvroPayload - Check merge mode and payload class before throwing exception for null precombine - Skip exception for RecordMergeMode.COMMIT_TIME_ORDERING - Skip exception for OverwriteWithLatestAvroPayload - Use OrderingValues.getDefault() as fallback for null values when ordering not required - Add tests for both scenarios Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The precombine notion is deprecated since version 1.1, so use "Ordering field" instead of "Precombine/ordering field" in the error message for consistency.
Address review comment: Move the ordering value creation logic with null-checking to a private createOrderingValue() method to reduce code complexity in the main method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
666a57a to
8de9e14
Compare
|
Rebased with latest master and addressed review comments: 1. Extracted to private method: 2. Regarding SPARK record type: If you think we should add similar validation for SPARK records, please let me know the specific code path where this should be added. @hudi-bot run azure |
| * or COMMIT_TIME_ORDERING merge mode, null values are allowed and a default ordering value is used. | ||
| * For other cases, throws IllegalArgumentException if any ordering field has a null value. | ||
| */ | ||
| private def createOrderingValue(orderingFields: java.util.List[String], |
There was a problem hiding this comment.
minor.
how about getOrderingValue(...)
- Renamed createOrderingValue() to getOrderingValue() per reviewer suggestion - Fixed return type from OrderingValues to Comparable[_] to match OrderingValues.create() return type, fixing compilation errors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Addressed remaining review comments:
@hudi-bot run azure |
Codecov Report✅ All modified and coverable lines are covered by tests.
Additional details and impacted files@@ Coverage Diff @@
## master #18061 +/- ##
=============================================
- Coverage 57.28% 45.23% -12.06%
+ Complexity 18525 8418 -10107
=============================================
Files 1944 1186 -758
Lines 106137 60856 -45281
Branches 13121 6492 -6629
=============================================
- Hits 60799 27526 -33273
+ Misses 39619 30342 -9277
+ Partials 5719 2988 -2731
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Describe the issue this Pull Request addresses
Closes #18060
When records have null values in the precombine field, Hudi jobs fail with a cryptic error message that makes it difficult for users to diagnose the root cause:
This error provides no actionable information about which field has the null value, which record is problematic, or how to remediate the issue.
Summary and Changelog
This change adds explicit null-checking with a clear, actionable error message before attempting payload creation in
HoodieCreateRecordUtils.scala.Changes:
HoodieCreateRecordUtils.scalaOverwriteWithLatestAvroPayload)TestHoodieCreateRecordUtils.scalato verify the improved error handlingExample of improved error message:
Impact
No public API changes. This is a usability improvement that provides clearer error messages when data quality issues occur during ingestion.
Risk Level
low - The change only affects error handling and adds a null check before an operation that would fail anyway. The behavior for valid data remains unchanged.
Documentation Update
none - No new configs or features added. This is an error message improvement.
Contributor's checklist