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

Misleading Error Message when Upserting JSON Double Values using SpannerTemplate #3371

Open
ablx opened this issue Nov 7, 2024 · 1 comment
Assignees
Labels
priority: p2 type: bug Something isn't working

Comments

@ablx
Copy link
Contributor

ablx commented Nov 7, 2024

Edit: Looking closer to the code it seems that the information is already lost when spring-gcp gets the response from Spanner. However since the information exists somehwere I wonder if you could make this more transparent.


The Google Cloud Spanner documentation outlines the requirements for handling Double values in JSON. However, when attempting to upsert a Double value inside JSON using the SpannerTemplate, a confusing error message occurs, despite Spanner's direct handling of JSON Double inputs providing more descriptive feedback.

Steps to Reproduce:

Create a table using the following SQL:

CREATE TABLE Test (
    ID STRING(MAX) NOT NULL,
    DATA JSON
) PRIMARY KEY(ID);

Upsert the following Kotlin entity using SpannerTemplate:

val entity = TestEntity(
    id = "1",
    data = NumberData(297.3344693281405)
)
spannerTemplate.upsert(entity)

Expected Behavior:
A clear and descriptive error message explaining the issue with the Double value, similar to direct SQL interactions with Spanner (e.g., "Invalid JSON literal: Input number: 297.3344693281405 cannot round-trip through string representation").

Actual Behavior:
The following misleading error message is generated:

com.google.cloud.spanner.SpannerException: FAILED_PRECONDITION: io.grpc.StatusRuntimeException: FAILED_PRECONDITION: Invalid value for column DATA in table Test: Expected JSON.

Additional Context:

Directly executing the following query in Spanner produces a more informative error message:

SELECT JSON '297.3344693281405'

Statement failed: Invalid JSON literal: Input number: 297.3344693281405 cannot round-trip through string representation

If the number is wrapped inside a JSON object, a similarly helpful error message is returned:

 SELECT JSON '{"foo": 297.3344693281405 }';

Invalid JSON literal: Input number: 297.3344693281405 cannot round-trip through string representation

Request:

Please ensure that SpannerTemplate provides a more accurate error message when handling JSON Double values to avoid confusion and aid in debugging.

Appendix:

Full StackTrace:

FAILED_PRECONDITION: io.grpc.StatusRuntimeException: FAILED_PRECONDITION: Invalid value for column DATA in table Test: Expected JSON.
com.google.cloud.spanner.SpannerException: FAILED_PRECONDITION: io.grpc.StatusRuntimeException: FAILED_PRECONDITION: Invalid value for column DATA in table Test: Expected JSON.
	at app//com.google.cloud.spanner.SpannerExceptionFactory.newSpannerExceptionPreformatted(SpannerExceptionFactory.java:309)
	at app//com.google.cloud.spanner.SpannerExceptionFactory.fromApiException(SpannerExceptionFactory.java:329)
	at app//com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException(SpannerExceptionFactory.java:181)
	at app//com.google.cloud.spanner.SpannerExceptionFactory.newSpannerException(SpannerExceptionFactory.java:110)
	at app//com.google.cloud.spanner.SpannerExceptionFactory.asSpannerException(SpannerExceptionFactory.java:100)
	at app//com.google.cloud.spanner.TransactionRunnerImpl$TransactionContextImpl$CommitRunnable.lambda$run$0(TransactionRunnerImpl.java:458)
	at app//com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
	at app//com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1300)
	at app//com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1061)
	at app//com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:811)
	at app//com.google.api.gax.retrying.BasicRetryingFuture.handleAttempt(BasicRetryingFuture.java:202)
	at app//com.google.api.gax.retrying.CallbackChainRetryingFuture$AttemptCompletionListener.handle(CallbackChainRetryingFuture.java:135)
	at app//com.google.api.gax.retrying.CallbackChainRetryingFuture$AttemptCompletionListener.run(CallbackChainRetryingFuture.java:117)
	at app//com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
	at app//com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1300)
	at app//com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1061)
	at app//com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:811)
	at app//com.google.api.core.AbstractApiFuture$InternalSettableFuture.setException(AbstractApiFuture.java:92)
	at app//com.google.api.core.AbstractApiFuture.setException(AbstractApiFuture.java:74)
	at app//com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
	at app//com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:84)
	at app//com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1130)
	at app//com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
	at app//com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1300)
	at app//com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1061)
	at app//com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:811)
	at app//io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:568)
	at app//io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:538)
	at app//io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
	at app//io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
	at app//io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
	at app//com.google.api.gax.grpc.ChannelPool$ReleasingClientCall$1.onClose(ChannelPool.java:569)
	at app//io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
	at app//io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
	at app//io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
	at app//io.grpc.PartialForwardingClientCallListener.onClose(PartialForwardingClientCallListener.java:39)
	at app//io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:23)
	at app//io.grpc.ForwardingClientCallListener$SimpleForwardingClientCallListener.onClose(ForwardingClientCallListener.java:40)
	at app//com.google.cloud.spanner.spi.v1.SpannerErrorInterceptor$1$1.onClose(SpannerErrorInterceptor.java:100)
	at app//io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:564)
	at app//io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:72)
	at app//io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:729)
	at app//io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:710)
	at app//io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
	at app//io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
	at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at [email protected]/java.lang.Thread.run(Thread.java:840)
Caused by: io.grpc.StatusRuntimeException: FAILED_PRECONDITION: Invalid value for column DATA in table Test: Expected JSON.
	at app//io.grpc.Status.asRuntimeException(Status.java:532)
	... 21 more

@ablx ablx changed the title Misleading error message if a number inside a json object is too large Misleading Error Message when Upserting JSON Double Values using SpannerTemplate Nov 7, 2024
@ablx
Copy link
Contributor Author

ablx commented Nov 11, 2024

It would be helpful to somehow set the wide_number_mode as suggested inhttps://cloud.google.com/spanner/docs/working-with-json#specs

@burkedavison burkedavison added priority: p2 type: bug Something isn't working labels Nov 11, 2024
@jinseopkim0 jinseopkim0 self-assigned this Feb 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p2 type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants