Skip to content

Preserve checked I/O failures in tree type adapters - #3130

Open
jakezwang wants to merge 4 commits into
google:mainfrom
jakezwang:fix/tree-adapter-ioexception
Open

jakezwang wants to merge 4 commits into
google:mainfrom
jakezwang:fix/tree-adapter-ioexception

Conversation

@jakezwang

@jakezwang jakezwang commented Sep 26, 2026 •

Copy link
Copy Markdown

Purpose

Closes #1907. Preserve the original checked IOException when TypeAdapter.read / TypeAdapter.fromJson(Reader) encounters a stream failure while reading a registered JsonDeserializer's JSON tree.

Description

Streams.parse wraps a reader's I/O failures in JsonIOException. Unwrap that specific exception at the streaming TreeTypeAdapter boundary, where read already declares IOException. This lets callers handle errors such as a socket timeout consistently with other streaming adapters.

The catch only surrounds tree parsing: exceptions deliberately thrown by a custom deserializer retain their existing type and identity. Empty-document and malformed-JSON handling in Streams.parse remains in place. This does not change the broader Gson.fromJson I/O-exception policy discussed in #1112 / #1023.

Added regression coverage for a SocketTimeoutException before any input and in the middle of an object, plus a custom-deserializer exception preservation check and an incomplete-array regression that keeps EOFException wrapped in JsonSyntaxException. The checked-I/O test fails before the fix.

Validation on JDK 17: mvn clean verify javadoc:jar passed for every reactor module, including formatting, JPMS, ProGuard/R8, extras, metrics, and protobuf. The Gson module ran 4,676 tests with 20 skipped and no failures/errors. After moving reader construction outside assertThrows to satisfy the JDK 21+ Error Prone check, the focused TreeTypeAdaptersTest suite also passed.

Checklist

  • New code follows the Google Java Style Guide (spotless passed).
  • Unit tests use Truth assertions and JUnit 4.
  • A regression test fails before the fix and passes afterward.
  • mvn clean verify javadoc:jar passes without errors.
  • Public API additions and associated Javadoc: not applicable.

Implementation and validation were performed primarily with OpenAI Codex.

Signed-off-by: Jake Wang <jakezwang@users.noreply.github.com>
@google-cla

google-cla Bot commented Sep 26, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Signed-off-by: Jake Wang <jakezwang@users.noreply.github.com>

@eamonnmcmanus eamonnmcmanus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! While this is technically a behaviour change, it is replacing one exception with another, so the risk of breakage seems minor. Meanwhile it does seem like a more consistent result.

I ran this past all of Google's internal tests and there were no failures.

@eamonnmcmanus

Copy link
Copy Markdown
Member

(We do need the CLA to be signed before we can accept this change, though.)

@Marcono1234

Marcono1234 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Would a test for EOFException be useful as well? EOFException extends IOException but is wrapped by Streams as JsonSyntaxException so it should probably not be unwrapped.

Maybe trying to deserialize something like "[" already suffices to trigger this, for which JsonReader should throw the EOFException, but the caller of TypeAdapter#fromJson should still receive it as JsonSyntaxException.

@jakezwang

Copy link
Copy Markdown
Author

Added the EOF regression in ad0db44. Deserializing [ through TypeAdapter.fromJson(Reader) must throw JsonSyntaxException with an EOFException cause, so checked-I/O unwrapping cannot accidentally change truncated-JSON handling. The full mvn clean verify javadoc:jar reactor passes on JDK 17, including 4,676 Gson-module tests (20 skipped, no failures/errors).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TreeTypeAdapter.read() may incorrectly hide IOException from InputStream as JsonIOException

3 participants