Fix broken errors thrown by JSONDecoder when parsing decimal as Int#1606
Fix broken errors thrown by JSONDecoder when parsing decimal as Int#1606hiragram wants to merge 1 commit intoswiftlang:mainfrom
JSONDecoder when parsing decimal as Int#1606Conversation
…iftlang#1604) This commit fixes the regression where JSONDecoder returns incorrect error information when attempting to decode a decimal value (e.g., 123.45) as Int. **Root Cause (from git history investigation):** - Initial implementation (commit 34c45c1, 2023-03-15) had correct error handling - BufferView refactoring (commit 1ab3832, 2023-04-03) accidentally removed the proper DecodingError.dataCorrupted throw statements - This caused JSONError.numberIsNotRepresentableInSwift to be caught at the top level and converted to a generic error with empty codingPath **Changes:** - Restored proper error handling in `_slowpath_unwrapFixedWidthInteger` - Changed JSONError.numberIsNotRepresentableInSwift throws to DecodingError.dataCorrupted with correct codingPath and debugDescription - Added regression test to prevent future breakage **Before (broken):** - codingPath: [] (empty) - debugDescription: "The given data was not valid JSON." **After (fixed):** - codingPath: ["foo"] - debugDescription: "Parsed JSON number <123.45> does not fit in Int." Fixes swiftlang#1604 Related: swiftlang#274
f93383c to
33761ab
Compare
|
@swift-ci please test |
| static private func _slowpath_unwrapFixedWidthInteger<T: FixedWidthInteger>(as type: T.Type, json5: Bool, numberBuffer: BufferView<UInt8>, fullSource: BufferView<UInt8>, digitBeginning: BufferViewIndex<UInt8>, for codingPathNode: _CodingPathNode, _ additionalKey: (some CodingKey)?) throws -> T { | ||
| // Helper function to create number conversion error | ||
| func createNumberConversionError() -> DecodingError { | ||
| #if FOUNDATION_FRAMEWORK |
There was a problem hiding this comment.
I don't think we need to preserve this existing (broken) behavior for FOUNDATION_FRAMEWORK as long as underlyingError's error code is untouched... @kperryua what do you think?
There was a problem hiding this comment.
@itingliu Thanks for your review. Just to confirm, are you saying that underlyingError should always be
nil on all platforms in this case?
There is existing code that switches the presence of underlyingError based on the FOUNDATION_FRAMEWORK flag, which I used as a reference. I don't fully understand the intent behind it, but I think it would be better to keep the behavior consistent.
There was a problem hiding this comment.
In retrospect, a JSONError seems incorrect here to begin with, as we've already pre-validated the buffer and successfully parsed some a number. Hence, it's valid JSON. (If we fail to parse, we call validateNumber afterwards, which gives us a JSONError that tells us exactly what's wrong.)
We should just be throwing the dataCorrupted error with no underlying error at all, on all platforms.
There was a problem hiding this comment.
@kperryua Should that be handled in this Pull Request? Personally, I think it's better to first fix the specific broken behaviors and have the discussion about what the "grand design" should look like in a separate thread.
There was a problem hiding this comment.
I wouldn’t consider this a “grand design” change. It’s a simplification of this PR by virtue of realigning this particular error throwing instance with the correct layering of errors. Nothing about the PR needs to change except eliding the creation of the underlying error (and the corresponding test code).
|
@swift-ci please test |
|
Sorry, I meant to click "comment" but clicked "close" accidentally. |
|
@swift-ci please test |
|
@swift-ci please test windows platform |
|
@itingliu anything to do before this getting merged? |
|
@itingliu ping 😄 |
fixes: #1604
This PR fixes a regression in
JSONDecoderwhere attempting to decode incompatible numeric values (e.g., decimal123.45asInt, or negative-123asUInt) returns incorrect error information. The bug affects both thecodingPath(empty instead of correct path) anddebugDescription(generic message instead of specific error details).See more detail: #1604