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

fix: update StorageException translation of an ApiException to include error details #2872

Merged
merged 2 commits into from
Jan 23, 2025

Conversation

BenWhitehead
Copy link
Collaborator

Update StorageException logic for coalescing ApiExceptions to add a formatted string including fields from error details as a suppressed exception on the api exception.

This keeps the diagnostic information at the "gapic layer" in the printed stacktrace similar to the json document being on the "apiary layer" of the cause.

The change here will produce something like the following:

com.google.cloud.storage.StorageException: OUT_OF_RANGE
	at com.google.cloud.storage.StorageException.asStorageException(StorageException.java:165)
	at com.google.cloud.storage.StorageException.coalesce(StorageException.java:123)
	at com.google.cloud.storage.StorageExceptionGrpcCompatibilityTest.apiExceptionErrorDetails(StorageExceptionGrpcCompatibilityTest.java:191)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
       [[...junit...]]
Caused by: com.google.api.gax.rpc.OutOfRangeException: io.grpc.StatusRuntimeException: OUT_OF_RANGE
	at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:106)
	at com.google.cloud.storage.StorageExceptionGrpcCompatibilityTest.apiExceptionErrorDetails(StorageExceptionGrpcCompatibilityTest.java:185)
	... 27 more
	Suppressed: com.google.cloud.storage.StorageException$ApiExceptionErrorDetailsComment: ErrorDetails {
		ErrorInfo: {reason: "STACKOUT" domain: "spanner.googlepais.com" metadata { key: "availableRegions" value: "us-central1,us-east2" } }
		DebugInfo: {stack_entries: "HEAD" stack_entries: "HEAD~1" stack_entries: "HEAD~2" stack_entries: "HEAD~3" detail: "some detail" }
		QuotaFailure: {violations { subject: "clientip:127.0.3.3" description: "Daily limit" } }
		PreconditionFailure: {violations { type: "TOS" subject: "google.com/cloud" description: "Terms of service not accepted" } }
		BadRequest: {field_violations { field: "email_addresses[3].type[2]" description: "duplicate value \'WORK\'" reason: "INVALID_EMAIL_ADDRESS_TYPE" localized_message { locale: "en-US" message: "Invalid email type: duplicate value" } } }
		Help: {links { description: "link1" url: "https://google.com" } }
	}
Caused by: io.grpc.StatusRuntimeException: OUT_OF_RANGE
	at io.grpc.Status.asRuntimeException(Status.java:524)
	at com.google.cloud.storage.StorageExceptionGrpcCompatibilityTest.apiExceptionErrorDetails(StorageExceptionGrpcCompatibilityTest.java:186)
	... 27 more

@BenWhitehead BenWhitehead requested a review from a team as a code owner January 9, 2025 22:26
@product-auto-label product-auto-label bot added size: m Pull request size is medium. api: storage Issues related to the googleapis/java-storage API. labels Jan 9, 2025
@BenWhitehead BenWhitehead force-pushed the api-exception-error-details branch from dbfe59e to 8a679df Compare January 9, 2025 23:37
…e error details

Update StorageException logic for coalescing ApiExceptions to add a formatted string including fields from error details as a suppressed exception on the api exception.

This keeps the diagnostic information at the "gapic layer" in the printed stacktrace similar to the json document being on the "apiary layer" of the cause.
@BenWhitehead BenWhitehead force-pushed the api-exception-error-details branch from 8a679df to 7bd8545 Compare January 9, 2025 23:45
Copy link
Contributor

@danielduhh danielduhh left a comment

Choose a reason for hiding this comment

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

Were we always missing ErrorInfo + details? What happened?

private static void attachErrorDetails(ApiException ae) {
if (ae != null && ae.getErrorDetails() != null) {
final StringBuilder sb = new StringBuilder();
ErrorDetails ed = ae.getErrorDetails();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does ErrorDetails have a toString function? Shouldn't this be handled there? My only concern is if any new fields are added, we'd have remember to pull it into this function

Copy link
Collaborator Author

@BenWhitehead BenWhitehead Jan 22, 2025

Choose a reason for hiding this comment

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

It does have a toString, however that will print out the packed protobuf bytes rather than the actual fields and info contained within.

The default toString:

ErrorDetails{rawErrorMessages=[type_url: "type.googleapis.com/google.rpc.ErrorInfo"
value: "\n\bSTACKOUT\022\026spanner.googlepais.com\032(\n\020availableRegions\022\024us-central1,us-east2"
, type_url: "type.googleapis.com/google.rpc.DebugInfo"
value: "\n\004HEAD\n\006HEAD~1\n\006HEAD~2\n\006HEAD~3\022\vsome detail"
, type_url: "type.googleapis.com/google.rpc.QuotaFailure"
value: "\n!\n\022clientip:127.0.3.3\022\vDaily limit"
, type_url: "type.googleapis.com/google.rpc.PreconditionFailure"
value: "\n6\n\003TOS\022\020google.com/cloud\032\035Terms of service not accepted"
, type_url: "type.googleapis.com/google.rpc.BadRequest"
value: "\n~\n\032email_addresses[3].type[2]\022\026duplicate value \'WORK\'\032\032INVALID_EMAIL_ADDRESS_TYPE\",\n\005en-US\022#Invalid email type: duplicate value"
, type_url: "type.googleapis.com/google.rpc.Help"
value: "\n\033\n\005link1\022\022https://google.com"
]}

Compared with our formatting:

ErrorDetails {
		ErrorInfo: { reason: "STACKOUT" domain: "spanner.googlepais.com" metadata { key: "availableRegions" value: "us-central1,us-east2" } }
		DebugInfo: { stack_entries: "HEAD" stack_entries: "HEAD~1" stack_entries: "HEAD~2" stack_entries: "HEAD~3" detail: "some detail" }
		QuotaFailure: { violations { subject: "clientip:127.0.3.3" description: "Daily limit" } }
		PreconditionFailure: { violations { type: "TOS" subject: "google.com/cloud" description: "Terms of service not accepted" } }
		BadRequest: { field_violations { field: "email_addresses[3].type[2]" description: "duplicate value \'WORK\'" reason: "INVALID_EMAIL_ADDRESS_TYPE" localized_message { locale: "en-US" message: "Invalid email type: duplicate value" } } }
		Help: { links { description: "link1" url: "https://google.com" } }
	}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this is much better. If changing the toString isnt a breaking change, we should add a follow up to fix this there

@BenWhitehead
Copy link
Collaborator Author

The information itself has always been present in the cause of the StorageException, but it required calling into it to access the info. This change mainly includes it in the stacktrace so that it is printed implicitly.

@BenWhitehead BenWhitehead merged commit 8ad5010 into main Jan 23, 2025
21 checks passed
@BenWhitehead BenWhitehead deleted the api-exception-error-details branch January 23, 2025 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: storage Issues related to the googleapis/java-storage API. size: m Pull request size is medium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants