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

feat: improve error response messages #614

Merged
merged 1 commit into from
Nov 1, 2024
Merged

Conversation

ricellis
Copy link
Member

PR summary

Add interceptor for error response augmentation

Fixes: s1002

Note: An existing issue is required before opening a PR.

PR Checklist

Please make sure that your PR fulfills the following requirements:

  • The commit message follows the
    Angular Commit Message Guidelines.
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • New tests
  • Build/CI related changes
  • Documentation content changes
  • Other (please describe)

What is the current behavior?

Cloudant/CouchDB error models are handled by the core with only the error field being processed. Obtaining e.g. the reason field requires additional user code.

What is the new behavior?

The error response is augmented with errors and trace properties.
This improves the way the core handles the error response and enhances the user facing exception string to include the reason.
The trace is the CouchDB request ID which can be used to correlate with logs.

Does this PR introduce a breaking change?

  • Yes
  • No

The existing error model fields are retained, the new fields are backwards compatible.
Exception strings will be different, but the types remain the same.

Other information

Add ErrorTransformInterceptor.
Modify CloudantBaseService to apply interceptor.
New tests in ErrorTransformInterceptorTest and CloudantErrorInterceptorTest.

@ricellis ricellis self-assigned this Oct 17, 2024
@emlaver emlaver force-pushed the s1002-error-augmentation branch from a5e8c90 to 79ba202 Compare October 17, 2024 20:59
@ricellis ricellis force-pushed the s1002-error-augmentation branch from 79ba202 to f0cf7fd Compare October 18, 2024 07:49
Copy link
Member

@eiri eiri left a comment

Choose a reason for hiding this comment

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

A couple of nits, but overall looks good to me

public Response intercept(Chain chain) throws IOException {
// Don't modify the request, but get the response
Response response = chain.proceed(chain.request());
if (!"HEAD".equals(chain.request().method()) // skip HEAD requests because they have no body
Copy link
Member

Choose a reason for hiding this comment

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

This is redundant with response.body() != null below

Copy link
Contributor

Choose a reason for hiding this comment

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

I would keep it if there's an event where the response of a non-HEAD request fails and the body doesn't exist.

Copy link
Member

Choose a reason for hiding this comment

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

I mean it's other way around - we don't need HEAD check if we already have check for body not been null 😄

Copy link
Member Author

@ricellis ricellis Oct 31, 2024

Choose a reason for hiding this comment

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

I think @eiri means that we could skip the HEAD check and just use the body check, but if we want to do that we need to be sure on the subtlety any of empty string vs null

Copy link
Contributor

@emlaver emlaver Oct 31, 2024

Choose a reason for hiding this comment

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

Ok, I'm open to removing HEAD check. If the body is not null and just empty, the GSON deserialize code should returns a null response. Here's the doc for fromJson:

Returns:
an object of type T from the string. Returns null if json is null or if json is empty.

If we don't want it to reach that code then we can add a response.body().toString().isEmpty() check.

Edited: Tried out the change in a branch and seems to work fine. Also added a test (to verify) for GET request with no body and that passes.

Copy link
Contributor

Choose a reason for hiding this comment

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

updated in 8411bd3

if (errorBody != null) {
// Don't augment if there is already a trace present
if (!errorBody.has("trace")) {
String error = Optional.ofNullable(errorBody.get("error")).map(JsonElement::getAsString).orElse(null);
Copy link
Member

Choose a reason for hiding this comment

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

A nit, but logically those two lines fit better after if (!errorBody.has("errors")) { check

Copy link
Contributor

Choose a reason for hiding this comment

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

updated in 8411bd3

Add ErrorTransformInterceptor.
Modify CloudantBaseService to apply interceptor.
New tests in ErrorTransformInterceptorTest and CloudantErrorInterceptorTest.

Co-authored-by: Rich Ellis <[email protected]>
@emlaver emlaver force-pushed the s1002-error-augmentation branch from 8411bd3 to 1369e17 Compare November 1, 2024 15:37
@emlaver emlaver merged commit b446af8 into main Nov 1, 2024
9 checks passed
@emlaver emlaver deleted the s1002-error-augmentation branch November 1, 2024 15:59
@ricellis ricellis mentioned this pull request Nov 6, 2024
13 tasks
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.

4 participants