Skip to content
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

Deserialize endpoint errors #2443

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open

Conversation

mpritham
Copy link
Contributor

@mpritham mpritham commented Dec 5, 2024

Before this PR

We'd like to support the a new method in BodySerDe that allows the creation of deserializers given an expected result type, and a set of expected error types.

A ConjureError is serialized and sent by servers. Dialogue deserializes the errors to a SerializableError which loses the type information of the parameters. By providing the type information of the parameters, Dialogue can deserialize the received ConjureError into the well-typed objects (instead of Strings).

After this PR

==COMMIT_MSG==

==COMMIT_MSG==

Possible downsides?

@changelog-app
Copy link

changelog-app bot commented Dec 5, 2024

Generate changelog in changelog/@unreleased

What do the change types mean?
  • feature: A new feature of the service.
  • improvement: An incremental improvement in the functionality or operation of the service.
  • fix: Remedies the incorrect behaviour of a component of the service in a backwards-compatible way.
  • break: Has the potential to break consumers of this service's API, inclusive of both Palantir services
    and external consumers of the service's API (e.g. customer-written software or integrations).
  • deprecation: Advertises the intention to remove service functionality without any change to the
    operation of the service itself.
  • manualTask: Requires the possibility of manual intervention (running a script, eyeballing configuration,
    performing database surgery, ...) at the time of upgrade for it to succeed.
  • migration: A fully automatic upgrade migration task with no engineer input required.

Note: only one type should be chosen.

How are new versions calculated?
  • ❗The break and manual task changelog types will result in a major release!
  • 🐛 The fix changelog type will result in a minor release in most cases, and a patch release version for patch branches. This behaviour is configurable in autorelease.
  • ✨ All others will result in a minor version release.

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

Check the box to generate changelog(s)

  • Generate changelog entry

@mpritham mpritham force-pushed the pm/endpoint-error-serde branch 5 times, most recently from 6081541 to 74008d5 Compare December 6, 2024 18:29
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from 74008d5 to a46dd8b Compare January 7, 2025 18:06
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from a46dd8b to c6dfe0c Compare January 7, 2025 18:10
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch 4 times, most recently from eb93b54 to 3b2987f Compare January 8, 2025 19:29
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch 4 times, most recently from 3ae5194 to a665dbf Compare January 8, 2025 21:24
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from a665dbf to 5221bb9 Compare January 8, 2025 21:37
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch 6 times, most recently from 6012f80 to 32885e2 Compare January 9, 2025 17:58
Comment on lines 146 to 162
String jsonContentType = "application/json";
if (contentType.isPresent() && Encodings.matchesContentType(jsonContentType, contentType.get())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps we update this to leverage the Encoding with something along these lines?

Encodings.matchesContentType(JSON_ENCODING.getContentType(), contentType.get())

If it's not terribly troublesome, we may want to take the existing json encoding from the configured set of encodings when it's present, and create a new one as a fallback. This way if the client is configured with encodings wrapped to produce metrics/etc, we can retain that functionality.

Comment on lines 149 to 150
JsonNode node = MAPPER.readTree(body);
JsonNode errorNameNode = node.get("errorName");
Copy link
Contributor

Choose a reason for hiding this comment

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

As written we're fully transforming the input json into a JsonNode tree, and reading at most a single string element.
We can define something like this to allow jackson to extract only the pieces of data we're interested in:

private record NamedError(@JsonProperty("errorName") String errorName) {}

@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from 32885e2 to 4ef5fe8 Compare January 9, 2025 18:26
@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from 4ef5fe8 to 7dac6ee Compare January 9, 2025 22:14
Comment on lines 197 to 199
try (Reader reader = new InputStreamReader(body, StandardCharsets.UTF_8)) {
return CharStreams.toString(reader).getBytes(StandardCharsets.UTF_8);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to convert the bytestream into a charstream (reader) to then convert back again in the other direction!

Suggested change
try (Reader reader = new InputStreamReader(body, StandardCharsets.UTF_8)) {
return CharStreams.toString(reader).getBytes(StandardCharsets.UTF_8);
}
try (body) {
return body.readAllBytes();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤦 This was dumb. Fixed.

Comment on lines 190 to 191
SerializableError serializableError = JSON_ENCODING
.deserializer(new TypeMarker<SerializableError>() {})
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we initialize this Deserializer<SerializableError> once above, rather than creating it anew each time it's needed?

Maps.transformValues(errorNameToTypeMap, maybeJsonEncoding.orElse(JSON_ENCODING)::deserializer));
}

public boolean isError(Response response) {
Copy link
Contributor

Choose a reason for hiding this comment

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

we can remove public from all the utility methods here, since the class itself is package private

@mpritham mpritham force-pushed the pm/endpoint-error-serde branch from fad1f82 to c67cb58 Compare January 10, 2025 19:28
@carterkozak
Copy link
Contributor

Looks solid -- want to start on the codegen piece using an RC?

@mpritham
Copy link
Contributor Author

Yep. Added do-not-merge. Need a +1 to cut the RC.

carterkozak
carterkozak previously approved these changes Jan 10, 2025
Copy link
Contributor

@carterkozak carterkozak left a comment

Choose a reason for hiding this comment

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

Approving to cut an RC for iteration with conjure-java codegen 👍

@policy-bot policy-bot bot dismissed stale reviews from carterkozak January 10, 2025 21:26

Invalidated by push of ae9dfff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants