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

RemoteException.getMessage includes SerializableError parameters #633

Merged
merged 2 commits into from
Apr 21, 2022

Conversation

carterkozak
Copy link
Contributor

In connected environments this makes no difference because
RemoteException.getMessage is never called, only getLogMessage.
In such cases the error instance identifier is sufficient to
search for the original failure information, however service
authors without safe-logging infrastructure are unlikely to have
access to remote instance logging and should be presented with
the failure parameters in local logging.

The message is computed lazily, very slightly reducing overhead
in environments that don't use the unsafe message, while providing
additional actionable signal to others.

After this PR

==COMMIT_MSG==
RemoteException.getMessage (unsafe message) includes SerializableError parameters. RemoteException.getLogMessage (safe) is not impacted.
==COMMIT_MSG==

@changelog-app
Copy link

changelog-app bot commented Feb 23, 2021

Generate changelog in changelog/@unreleased

Type

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

Description

RemoteException.getMessage (unsafe message) includes SerializableError parameters. RemoteException.getLogMessage (safe) is not impacted.

Check the box to generate changelog(s)

  • Generate changelog entry

In connected environments this makes no difference because
RemoteException.getMessage is never called, only getLogMessage.
In such cases the error instance identifier is sufficient to
search for the original failure information, however service
authors without safe-logging infrastructure are unlikely to have
access to remote instance logging and should be presented with
the failure parameters in local logging.

The message is computed lazily, very slightly reducing overhead
in environments that don't use the unsafe message, while providing
additional actionable signal to others.
@carterkozak carterkozak force-pushed the ckozak/unsafelog_remoteexception_args branch from 454d5d6 to 0bf9c2e Compare February 23, 2021 20:12
@carterkozak carterkozak removed the request for review from ferozco February 23, 2021 21:02
@pkoenig10
Copy link
Member

pkoenig10 commented Feb 23, 2021

Just want to flag that we previously rejected this change in #337. I'm not opposed to making this change (I think I'd actually prefer it), I just want to ensure that we're now willing to accept the tradeoffs here.

@carterkozak
Copy link
Contributor Author

Yep yep, Felix reported a case where an issue was difficult to debug due to lack of insight into the server-side of the problem, recorded in a non-safe-logging environment. I think that’s the upside we were missing last time.

.forEach((name, unsafeValue) ->
builder.append(name).append('=').append(unsafeValue).append(", "));
// remove the trailing space
builder.setLength(builder.length() - 1);

Choose a reason for hiding this comment

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

Joiner? Does that allocate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In this case it's unlikely that the last character resulted in a buffer expansion, so reducing the length by 1 is a non-volatile write to the StringBuilder.count integer.

Joiner would work nicely if this didn't involve relatively complex prefix parameters -- we'd end up creating a bunch of intermediate strings.

@policy-bot policy-bot bot requested a review from robert3005 April 6, 2021 08:37
@stale
Copy link

stale bot commented May 6, 2021

This PR has been automatically marked as stale because it has not been touched in the last 14 days. If you'd like to keep it open, please leave a comment or add the 'long-lived' label, otherwise it'll be closed in 7 days.

@stale stale bot added the stale label May 6, 2021
@stale stale bot closed this Jun 11, 2021
@carterkozak carterkozak reopened this Apr 21, 2022
@stale stale bot removed the stale label Apr 21, 2022
@carterkozak carterkozak requested a review from fawind April 21, 2022 10:53
this.error = error;
this.status = status;
this.args = Collections.singletonList(SafeArg.of("errorInstanceId", error.errorInstanceId()));
}

@Override
public String getMessage() {
return message;
// This field is not used in most environments so the cost of computation may be avoided.
String messageValue = unsafeMessage;
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious, why do we need the messageValue helper variable instead of doing something like:

if (unsafeMessage == null) {
    unsafeMessage = renderUnsafeMessage();
}
return unsafeMessage;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Optimization, not likely a measurable difference, but we’re reading the field value once instead of twice. I find it cleaner to assert on the same value that’s returned as well (avoids a class of race condition bugs)

: String.format("RemoteException: %s (%s)", error.errorCode(), error.errorName());
this.message = this.stableMessage + " with instance ID " + error.errorInstanceId();
? "RemoteException: " + error.errorCode()
: "RemoteException: " + error.errorCode() + " (" + error.errorName() + ")";
this.error = error;
this.status = status;
this.args = Collections.singletonList(SafeArg.of("errorInstanceId", error.errorInstanceId()));
}

@Override
public String getMessage() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also add the new safety annotations to this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wouldn’t hurt, although we already consider throwable.getMessage unsafe across the board

@fmance fmance removed their request for review April 21, 2022 12:03
Copy link
Contributor

@fawind fawind left a comment

Choose a reason for hiding this comment

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

Looks good, especially given that even previously this was positively received, just lacking an incentive.

@bulldozer-bot bulldozer-bot bot merged commit a6faf12 into develop Apr 21, 2022
@bulldozer-bot bulldozer-bot bot deleted the ckozak/unsafelog_remoteexception_args branch April 21, 2022 13:30
@svc-autorelease
Copy link
Collaborator

Released 2.25.0

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.

None yet

5 participants