Honor @JsonView in ThrowableDeserializer.deserializeFromObject() - #6174
Conversation
@JsonView in ThrowableDeserializer.deserializeFromObject()
|
This may be problematic for common use cases due to 3.x enabling of EDIT: apparently only problematic with |
| private boolean _isStandardThrowableProperty(String propertyName) { | ||
| switch (propertyName) { | ||
| case PROP_NAME_CAUSE: | ||
| case PROP_NAME_STACK_TRACE: | ||
| case PROP_NAME_MESSAGE: | ||
| case PROP_NAME_LOCALIZED_MESSAGE: | ||
| case PROP_NAME_SUPPRESSED: | ||
| return true; | ||
| default: | ||
| return false; | ||
| } |
There was a problem hiding this comment.
💡 Edge Case: Standard-prop exemption bypassed by property naming strategy
_isStandardThrowableProperty matches property names with a case-sensitive switch on the literal Throwable names (cause, stackTrace, etc.). Under a PropertyNamingStrategy that renames properties (e.g. upper-camel), prop.getName() no longer equals these literals, so the standard property is not exempted and would again be filtered out under a restricted view. This is consistent with the pre-existing naming-strategy limitation noted at the message handling (databind#3497), so it is a minor gap rather than a regression; if broader coverage is desired, compare against the mangled names as done elsewhere.
Was this helpful? React with 👍 / 👎
Code Review 👍 Approved with suggestions 0 resolved / 1 findingsFixes 💡 Edge Case: Standard-prop exemption bypassed by property naming strategy📄 src/main/java/tools/jackson/databind/deser/jdk/ThrowableDeserializer.java:329-339 📄 src/main/java/tools/jackson/databind/deser/jdk/ThrowableDeserializer.java:135-136
🤖 Prompt for agentsOptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
|
Changed to include "standard" properties regardless. |
Conflict: `ThrowableDeserializer` import block -- FasterXML#6174 (`@JsonView`) added `ClassUtil`, this branch added `IgnorePropertiesUtil`; keep both. The two changes touch different parts of `deserializeFromObject()`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ViTmN932ZXuhpABmeGa6L9
BeanDeserializer and its array and builder variants skip properties that fall outside the active @JSONVIEW, but ThrowableDeserializer overrides deserializeFromObject on its own to handle the special message and cause construction, and that override never looked at the view. It only bites exceptions that reach this loop rather than the property-based-creator path: a Throwable with a default constructor and no @JsonCreator, where the remaining fields are plain setters. Under a restricted view those fields are still read straight from input, so a property that belongs only to another view (say an internal-only field on a custom exception) gets populated by a caller reading under a narrower view. I noticed it while checking which deserializers consult _needViewProcesing and this was the only property loop that did not. The fix reads the active view once and skips any property not visible in it before the value is set or deferred, matching what deserializeWithView already does, including the FAIL_ON_UNEXPECTED_VIEW_PROPERTIES behavior. I kept the change inside deserializeFromObject so the creator and any-setter paths are untouched.