From efc7765914cf46c4d07d3eac4bad6aeecf0862af Mon Sep 17 00:00:00 2001 From: Hazel Date: Mon, 26 Jan 2026 17:49:05 -0800 Subject: [PATCH 01/14] replace "EMBEDDING_PROVIDER_CLIENT_ERROR" --- .../sgv2/jsonapi/exception/ErrorCodeV1.java | 1 - .../operation/AwsBedrockEmbeddingProvider.java | 11 ++++++++--- .../embedding/operation/EmbeddingProvider.java | 11 ++++++++--- .../v1/tables/InsertOneTableIntegrationTest.java | 15 +++++++++------ .../EmbeddingProviderErrorMessageTest.java | 7 ++++--- .../operation/OpenAiEmbeddingClientTest.java | 15 +++++++-------- 6 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 5314b91b9e..0d09140faa 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -10,7 +10,6 @@ public enum ErrorCodeV1 { EMBEDDING_RESPONSE_DECODING_ERROR("Unable to parse embedding provider response message"), EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED( "The Embedding Provider authentication keys not provided"), - EMBEDDING_PROVIDER_CLIENT_ERROR("The Embedding Provider returned a HTTP client error"), EMBEDDING_PROVIDER_SERVER_ERROR("The Embedding Provider returned a HTTP server error"), EMBEDDING_PROVIDER_RATE_LIMITED("The Embedding Provider rate limited the request"), EMBEDDING_PROVIDER_TIMEOUT("The Embedding Provider timed out"), diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java index 9277c37cec..c8951dcd10 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java @@ -12,6 +12,7 @@ import com.google.common.io.CountingOutputStream; import io.smallrye.mutiny.Uni; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; @@ -176,9 +177,13 @@ private Throwable mapBedrockException(BedrockRuntimeException bedrockException) } if (bedrockException.statusCode() > 400 && bedrockException.statusCode() < 500) { - return ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), bedrockException.statusCode(), bedrockException.getMessage()); + return EmbeddingProviderException.Code.CLIENT_ERROR.get( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(bedrockException.statusCode()), + "errorMessage", + bedrockException.getMessage()); } if (bedrockException.statusCode() >= 500) { diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java index a4c2543927..c4bc6b4d92 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java @@ -6,6 +6,7 @@ import io.smallrye.mutiny.Uni; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.exception.ServerException; @@ -233,9 +234,13 @@ protected RuntimeException mapHTTPError(Response jakartaResponse, String errorMe // Status code in 4XX other than 429 if (jakartaResponse.getStatusInfo().getFamily() == CLIENT_ERROR) { - return ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage); + return EmbeddingProviderException.Code.CLIENT_ERROR.get( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(jakartaResponse.getStatus()), + "errorMessage", + errorMessage); } // Status code in 5XX diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java index 5486b4d730..af5343fc8f 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java @@ -8,7 +8,7 @@ import io.quarkus.test.common.WithTestResource; import io.quarkus.test.junit.QuarkusIntegrationTest; import io.stargate.sgv2.jsonapi.exception.DocumentException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.service.operation.filters.table.codecs.JSONCodecRegistryTestData; import io.stargate.sgv2.jsonapi.testresource.DseTestResource; import io.stargate.sgv2.jsonapi.util.Base64Util; @@ -1734,8 +1734,9 @@ void insertDifferentVectorizeDimensions() { } """) .hasSingleApiError( - ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR.name(), - "The Embedding Provider returned a HTTP client error: Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); + EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.class, + "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); } @Order(2) @@ -1782,8 +1783,9 @@ void insertDifferentVectorizeModels() { } """) .hasSingleApiError( - ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR.name(), - "The Embedding Provider returned a HTTP client error: Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); + EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.class, + "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); } @Order(3) @@ -1829,7 +1831,8 @@ void insertDifferentVectorizeProviders() { } """) .hasSingleApiError( - ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR, + EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.class, anyOf( containsString("Provider: openai; HTTP Status: 401; Error Message: "), containsString("Provider: jinaAI; HTTP Status: 401; Error Message: "))); diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java index 81f0538a3d..9a9ac07d83 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java @@ -7,6 +7,7 @@ import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; import io.stargate.sgv2.jsonapi.TestConstants; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; @@ -123,11 +124,11 @@ public void test4xx() throws Exception { var exception = vectorizeWithError("400"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR) + .isInstanceOf(EmbeddingProviderException.class) + .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider returned a HTTP client error: Provider: nvidia; HTTP Status: 400; Error Message: {\"object\":\"list\"}"); + "Provider: nvidia; HTTP Status: 400; Error Message: {\"object\":\"list\"}"); } @Test diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java index 542b27854d..1acc03645f 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java @@ -7,8 +7,7 @@ import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; import io.stargate.sgv2.jsonapi.TestConstants; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfigImpl; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; @@ -149,11 +148,11 @@ public void invalidOrg() throws Exception { "some data"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR) + .isInstanceOf(EmbeddingProviderException.class) + .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider returned a HTTP client error: Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); + "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); } @Test @@ -165,11 +164,11 @@ public void invalidProject() throws Exception { "some data"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_CLIENT_ERROR) + .isInstanceOf(EmbeddingProviderException.class) + .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider returned a HTTP client error: Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); + "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); } } } From 6561eb4b17e8816265d86e6a041530a56a1311dd Mon Sep 17 00:00:00 2001 From: Hazel Date: Tue, 27 Jan 2026 16:54:17 -0800 Subject: [PATCH 02/14] redo Tatu previous work --- .../exception/EmbeddingProviderException.java | 11 ++- .../sgv2/jsonapi/exception/ErrorCodeV1.java | 6 -- .../AwsBedrockEmbeddingProvider.java | 81 ++++++++++++++----- .../operation/EmbeddingProvider.java | 23 ++++-- src/main/resources/errors.yaml | 37 ++++++++- .../tables/InsertOneTableIntegrationTest.java | 6 +- .../operation/EmbeddingGatewayClientTest.java | 16 ++-- .../EmbeddingProviderErrorMessageTest.java | 18 +++-- .../operation/OpenAiEmbeddingClientTest.java | 6 +- 9 files changed, 143 insertions(+), 61 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 0148554746..7aa3bbf925 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -10,8 +10,15 @@ public EmbeddingProviderException(ErrorInstance errorInstance) { public enum Code implements ErrorCode { EMBEDDING_GATEWAY_NOT_AVAILABLE, - CLIENT_ERROR, - SERVER_ERROR; + + EMBEDDING_REQUEST_ENCODING_ERROR, + EMBEDDING_RESPONSE_DECODING_ERROR, + + EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED, + EMBEDDING_PROVIDER_CLIENT_ERROR, + EMBEDDING_PROVIDER_RATE_LIMITED, + EMBEDDING_PROVIDER_SERVER_ERROR, + ; private final ErrorTemplate template; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 0d09140faa..416e6ce710 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -6,12 +6,6 @@ public enum ErrorCodeV1 { /** Embedding provider service error codes. */ // !!! 16-Dec-2025, tatu: USED BY EMBEDDING-GATEWAY, DO NOT CONVERT "EMBEDDING_" entries yet - EMBEDDING_REQUEST_ENCODING_ERROR("Unable to create embedding provider request message"), - EMBEDDING_RESPONSE_DECODING_ERROR("Unable to parse embedding provider response message"), - EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED( - "The Embedding Provider authentication keys not provided"), - EMBEDDING_PROVIDER_SERVER_ERROR("The Embedding Provider returned a HTTP server error"), - EMBEDDING_PROVIDER_RATE_LIMITED("The Embedding Provider rate limited the request"), EMBEDDING_PROVIDER_TIMEOUT("The Embedding Provider timed out"), EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE("The Embedding Provider returned an unexpected response"), EMBEDDING_PROVIDER_API_KEY_MISSING("The Embedding Provider API key is missing"), diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java index c8951dcd10..39d703f248 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java @@ -74,19 +74,33 @@ public Uni vectorize( } if (embeddingCredentials.accessId().isEmpty() && embeddingCredentials.secretId().isEmpty()) { - throw ErrorCodeV1.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.toApiException( - "Both '%s' and '%s' are missing in the header for provider '%s'", - EMBEDDING_AUTHENTICATION_ACCESS_ID_HEADER_NAME, - EMBEDDING_AUTHENTICATION_SECRET_ID_HEADER_NAME, - modelProvider().apiName()); - } else if (embeddingCredentials.accessId().isEmpty()) { - throw ErrorCodeV1.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.toApiException( - "'%s' is missing in the header for provider '%s'", - EMBEDDING_AUTHENTICATION_ACCESS_ID_HEADER_NAME, modelProvider().apiName()); - } else if (embeddingCredentials.secretId().isEmpty()) { - throw ErrorCodeV1.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.toApiException( - "'%s' is missing in the header for provider '%s'", - EMBEDDING_AUTHENTICATION_SECRET_ID_HEADER_NAME, modelProvider().apiName()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.get( + Map.of( + "provider", + modelProvider().apiName(), + "message", + "both '%s' and '%s' headers are missing" + .formatted( + EMBEDDING_AUTHENTICATION_ACCESS_ID_HEADER_NAME, + EMBEDDING_AUTHENTICATION_SECRET_ID_HEADER_NAME))); + } + + if (embeddingCredentials.accessId().isEmpty()) { + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.get( + Map.of( + "provider", + modelProvider().apiName(), + "message", + "'%s' header is missing".formatted(EMBEDDING_AUTHENTICATION_ACCESS_ID_HEADER_NAME))); + } + + if (embeddingCredentials.secretId().isEmpty()) { + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.get( + Map.of( + "provider", + modelProvider().apiName(), + "message", + "'%s' header is missing".formatted(EMBEDDING_AUTHENTICATION_SECRET_ID_HEADER_NAME))); } var awsCreds = @@ -117,7 +131,14 @@ public Uni vectorize( bytesUsageTracker.requestBytes = inputData.length; requestBuilder.body(SdkBytes.fromByteArray(inputData)).modelId(modelName()); } catch (JsonProcessingException e) { - throw ErrorCodeV1.EMBEDDING_REQUEST_ENCODING_ERROR.toApiException(); + throw EmbeddingProviderException.Code.EMBEDDING_REQUEST_ENCODING_ERROR.get( + Map.of( + "provider", + modelProvider().apiName(), + "model", + modelName(), + "errorMessage", + e.toString())); } }) .thenApply( @@ -151,7 +172,14 @@ public Uni vectorize( batchId, List.of(bedrockResponse.embedding), modelUsage); } catch (IOException e) { - throw ErrorCodeV1.EMBEDDING_RESPONSE_DECODING_ERROR.toApiException(); + throw EmbeddingProviderException.Code.EMBEDDING_RESPONSE_DECODING_ERROR.get( + Map.of( + "provider", + modelProvider().apiName(), + "model", + modelName(), + "errorMessage", + e.toString())); } }); @@ -171,13 +199,18 @@ private Throwable mapBedrockException(BedrockRuntimeException bedrockException) } if (bedrockException.statusCode() == Response.Status.TOO_MANY_REQUESTS.getStatusCode()) { - return ErrorCodeV1.EMBEDDING_PROVIDER_RATE_LIMITED.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), bedrockException.statusCode(), bedrockException.getMessage()); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_RATE_LIMITED.get( + Map.of( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(bedrockException.statusCode()), + "errorMessage", + bedrockException.getMessage())); } if (bedrockException.statusCode() > 400 && bedrockException.statusCode() < 500) { - return EmbeddingProviderException.Code.CLIENT_ERROR.get( + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.get( "provider", modelProvider().apiName(), "httpStatus", @@ -187,9 +220,13 @@ private Throwable mapBedrockException(BedrockRuntimeException bedrockException) } if (bedrockException.statusCode() >= 500) { - return ErrorCodeV1.EMBEDDING_PROVIDER_SERVER_ERROR.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), bedrockException.statusCode(), bedrockException.getMessage()); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_SERVER_ERROR.get( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(bedrockException.statusCode()), + "errorMessage", + bedrockException.getMessage()); } // All other errors, Should never happen as all errors are covered above diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java index c4bc6b4d92..759ce93f85 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java @@ -227,14 +227,19 @@ protected RuntimeException mapHTTPError(Response jakartaResponse, String errorMe // Status code == 429 if (jakartaResponse.getStatus() == Response.Status.TOO_MANY_REQUESTS.getStatusCode()) { - return ErrorCodeV1.EMBEDDING_PROVIDER_RATE_LIMITED.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_RATE_LIMITED.get( + Map.of( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(jakartaResponse.getStatus()), + "errorMessage", + errorMessage)); } // Status code in 4XX other than 429 if (jakartaResponse.getStatusInfo().getFamily() == CLIENT_ERROR) { - return EmbeddingProviderException.Code.CLIENT_ERROR.get( + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.get( "provider", modelProvider().apiName(), "httpStatus", @@ -245,9 +250,13 @@ protected RuntimeException mapHTTPError(Response jakartaResponse, String errorMe // Status code in 5XX if (jakartaResponse.getStatusInfo().getFamily() == Response.Status.Family.SERVER_ERROR) { - return ErrorCodeV1.EMBEDDING_PROVIDER_SERVER_ERROR.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_SERVER_ERROR.get( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(jakartaResponse.getStatus()), + "errorMessage", + errorMessage); } // All other errors, Should never happen as all errors are covered above diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index 24a4aa1701..606c1449b2 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2579,13 +2579,42 @@ server-errors: Underlying problem: ${errorMessage}. - scope: EMBEDDING_PROVIDER - code: CLIENT_ERROR + code: EMBEDDING_REQUEST_ENCODING_ERROR + title: Embedding request encoding failure + body: |- + Internal error: failed to encode embedding request (provider '${provider}', model '${model}'). + Underlying problem: ${errorMessage} + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_RESPONSE_DECODING_ERROR + title: Embedding request response decoding failure + body: |- + Internal error: failed to decode response to embedding request (provider '${provider}', model '${model}'). + Underlying problem: ${errorMessage} + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED + title: Authentication header(s) missing from embedding request + body: |- + Missing authentication header(s) from embedding request (provider '${provider}'): ${message}'). + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_CLIENT_ERROR title: The Embedding Provider returned a HTTP client error body: |- Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_RATE_LIMITED + title: Embedding provider rate limited the request + body: |- + Provider '${provider}' rate limited the request with HTTP ${httpStatus}; error message: ${errorMessage} - scope: EMBEDDING_PROVIDER - code: SERVER_ERROR - title: The Embedding Provider returned a HTTP client error + code: EMBEDDING_PROVIDER_SERVER_ERROR + title: The Embedding Provider returned a HTTP server error body: |- - Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} \ No newline at end of file + Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} + + + diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java index af5343fc8f..94abeca868 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java @@ -1734,7 +1734,7 @@ void insertDifferentVectorizeDimensions() { } """) .hasSingleApiError( - EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); } @@ -1783,7 +1783,7 @@ void insertDifferentVectorizeModels() { } """) .hasSingleApiError( - EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); } @@ -1831,7 +1831,7 @@ void insertDifferentVectorizeProviders() { } """) .hasSingleApiError( - EmbeddingProviderException.Code.CLIENT_ERROR, + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, anyOf( containsString("Provider: openai; HTTP Status: 401; Error Message: "), diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java index 339702402c..97ea67d6d2 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java @@ -13,7 +13,8 @@ import io.stargate.embedding.gateway.EmbeddingService; import io.stargate.sgv2.jsonapi.TestConstants; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; +import io.stargate.sgv2.jsonapi.exception.APIException; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfigImpl; @@ -197,13 +198,12 @@ void handleError() { EmbeddingGateway.EmbeddingResponse.newBuilder(); EmbeddingGateway.EmbeddingResponse.ErrorResponse.Builder errorResponseBuilder = EmbeddingGateway.EmbeddingResponse.ErrorResponse.newBuilder(); - JsonApiException apiException = - ErrorCodeV1.EMBEDDING_PROVIDER_RATE_LIMITED.toApiException( - "Error Code : %s response description : %s", 429, "Too Many Requests"); + APIException apiException = + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_RATE_LIMITED.get( + Map.of( + "provider", "TEST-MODEL", "httpStatus", "429", "errorMessage", "Slow Down Dude!")); - errorResponseBuilder - .setErrorCode(apiException.getErrorCode().name()) - .setErrorMessage(apiException.getMessage()); + errorResponseBuilder.setErrorCode(apiException.code).setErrorMessage(apiException.getMessage()); builder.setError(errorResponseBuilder.build()); when(embeddingService.embed(any())).thenReturn(Uni.createFrom().item(builder.build())); @@ -239,7 +239,7 @@ void handleError() { e -> { JsonApiException exception = (JsonApiException) e; assertThat(exception.getMessage()).isEqualTo(apiException.getMessage()); - assertThat(exception.getErrorCode()).isEqualTo(apiException.getErrorCode()); + assertThat(exception.getErrorCode().name()).isEqualTo(apiException.code); }); } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java index 9a9ac07d83..7fe70e1ea0 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java @@ -7,6 +7,7 @@ import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; import io.stargate.sgv2.jsonapi.TestConstants; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; +import io.stargate.sgv2.jsonapi.exception.APIException; import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.exception.JsonApiException; @@ -111,11 +112,12 @@ public void test429() throws Exception { var exception = vectorizeWithError("429"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_RATE_LIMITED) + .isInstanceOf(APIException.class) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_RATE_LIMITED.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider rate limited the request: Provider: nvidia; HTTP Status: 429; Error Message: {\"object\":\"list\"}"); + "Provider 'nvidia' rate limited the request with HTTP 429; error message: {\"object\":\"list\"}"); } @Test @@ -125,7 +127,8 @@ public void test4xx() throws Exception { assertThat(exception) .isInstanceOf(EmbeddingProviderException.class) - .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", "Provider: nvidia; HTTP Status: 400; Error Message: {\"object\":\"list\"}"); @@ -137,11 +140,12 @@ public void test5xx() throws Exception { var exception = vectorizeWithError("503"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_SERVER_ERROR) + .isInstanceOf(EmbeddingProviderException.class) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_SERVER_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider returned a HTTP server error: Provider: nvidia; HTTP Status: 503; Error Message: {\"object\":\"list\"}"); + "Provider: nvidia; HTTP Status: 503; Error Message: {\"object\":\"list\"}"); } @Test diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java index 1acc03645f..e1fceb7f13 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java @@ -149,7 +149,8 @@ public void invalidOrg() throws Exception { assertThat(exception) .isInstanceOf(EmbeddingProviderException.class) - .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); @@ -165,7 +166,8 @@ public void invalidProject() throws Exception { assertThat(exception) .isInstanceOf(EmbeddingProviderException.class) - .hasFieldOrPropertyWithValue("code", EmbeddingProviderException.Code.CLIENT_ERROR.name()) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); From 28c218f1891ee694e952c91defcf250f5a78dbfc Mon Sep 17 00:00:00 2001 From: Hazel Date: Tue, 27 Jan 2026 18:06:41 -0800 Subject: [PATCH 03/14] fix the unit test --- .../exception/EmbeddingProviderException.java | 22 +++++++++++++++++++ .../gateway/EmbeddingGatewayClient.java | 14 +++++------- src/main/proto/embedding_gateway.proto | 3 ++- .../operation/EmbeddingGatewayClientTest.java | 12 +++++----- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 7aa3bbf925..292f811a96 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -1,5 +1,9 @@ package io.stargate.sgv2.jsonapi.exception; +import java.util.EnumSet; +import java.util.Optional; +import java.util.UUID; + public class EmbeddingProviderException extends ServerException { public static final Scope SCOPE = Scope.EMBEDDING_PROVIDER; @@ -8,6 +12,24 @@ public EmbeddingProviderException(ErrorInstance errorInstance) { super(errorInstance); } + /** + * To construct an EmbeddingProviderException from EGW response. + * + * @see io.stargate.sgv2.jsonapi.service.embedding.gateway.EmbeddingGatewayClient + */ + public EmbeddingProviderException(String code, String title, String body) { + this( + new ErrorInstance( + UUID.randomUUID(), + FAMILY, + SCOPE, + code, + title, + body, + Optional.empty(), + EnumSet.noneOf(ExceptionFlags.class))); + } + public enum Code implements ErrorCode { EMBEDDING_GATEWAY_NOT_AVAILABLE, diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java index 4baa4625fe..ab09c57e15 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java @@ -7,15 +7,12 @@ import io.stargate.embedding.gateway.EmbeddingService; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; import io.stargate.sgv2.jsonapi.api.request.tenant.Tenant; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; +import io.stargate.sgv2.jsonapi.exception.*; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; import io.stargate.sgv2.jsonapi.service.embedding.operation.EmbeddingProvider; import io.stargate.sgv2.jsonapi.service.provider.ModelProvider; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** Grpc client for embedding gateway service */ public class EmbeddingGatewayClient extends EmbeddingProvider { @@ -182,9 +179,10 @@ else if (value instanceof Boolean) .transform( gatewayResponse -> { if (gatewayResponse.hasError()) { - throw new JsonApiException( - ErrorCodeV1.valueOf(gatewayResponse.getError().getErrorCode()), - gatewayResponse.getError().getErrorMessage()); + throw new EmbeddingProviderException( + gatewayResponse.getError().getErrorCode(), + gatewayResponse.getError().getErrorTitle(), + gatewayResponse.getError().getErrorBody()); } // aaron - 10 June 2025 - previous code would silently swallow no data returned // but grpc will make sure resp.getEmbeddingsList() is never null diff --git a/src/main/proto/embedding_gateway.proto b/src/main/proto/embedding_gateway.proto index e7e2114d3c..06e1ae9099 100644 --- a/src/main/proto/embedding_gateway.proto +++ b/src/main/proto/embedding_gateway.proto @@ -68,7 +68,8 @@ message EmbeddingResponse { // The error response message for the embedding gateway gRPC API message ErrorResponse { string error_code = 1; - string error_message = 2; + string error_title = 2; + string error_body = 3; } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java index 97ea67d6d2..3875224e93 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingGatewayClientTest.java @@ -15,7 +15,6 @@ import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; import io.stargate.sgv2.jsonapi.exception.APIException; import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfigImpl; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; @@ -203,7 +202,10 @@ void handleError() { Map.of( "provider", "TEST-MODEL", "httpStatus", "429", "errorMessage", "Slow Down Dude!")); - errorResponseBuilder.setErrorCode(apiException.code).setErrorMessage(apiException.getMessage()); + errorResponseBuilder + .setErrorCode(apiException.code) + .setErrorTitle(apiException.title) + .setErrorBody(apiException.body); builder.setError(errorResponseBuilder.build()); when(embeddingService.embed(any())).thenReturn(Uni.createFrom().item(builder.build())); @@ -234,12 +236,12 @@ void handleError() { .getFailure(); assertThat(result) - .isInstanceOf(JsonApiException.class) + .isInstanceOf(APIException.class) .satisfies( e -> { - JsonApiException exception = (JsonApiException) e; + APIException exception = (APIException) e; assertThat(exception.getMessage()).isEqualTo(apiException.getMessage()); - assertThat(exception.getErrorCode().name()).isEqualTo(apiException.code); + assertThat(exception.code).isEqualTo(apiException.code); }); } } From 5baeba7ac7d9fff5d0ae3cb52fbb729de02dd309 Mon Sep 17 00:00:00 2001 From: Hazel Date: Wed, 28 Jan 2026 12:02:25 -0800 Subject: [PATCH 04/14] convert EMBEDDING_PROVIDER_TIMEOUT --- .../exception/EmbeddingProviderException.java | 1 + .../sgv2/jsonapi/exception/ErrorCodeV1.java | 1 - .../gateway/EmbeddingGatewayClient.java | 9 +++++- .../AwsBedrockEmbeddingProvider.java | 11 +++++-- .../operation/EmbeddingProvider.java | 31 +++++++++++-------- src/main/resources/errors.yaml | 6 +++- .../EmbeddingProviderErrorMessageTest.java | 8 ++--- .../operation/OpenAiEmbeddingClientTest.java | 2 -- 8 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 292f811a96..95c950f9d9 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -40,6 +40,7 @@ public enum Code implements ErrorCode { EMBEDDING_PROVIDER_CLIENT_ERROR, EMBEDDING_PROVIDER_RATE_LIMITED, EMBEDDING_PROVIDER_SERVER_ERROR, + EMBEDDING_PROVIDER_TIMEOUT, ; private final ErrorTemplate template; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 416e6ce710..35f309669c 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -8,7 +8,6 @@ public enum ErrorCodeV1 { // !!! 16-Dec-2025, tatu: USED BY EMBEDDING-GATEWAY, DO NOT CONVERT "EMBEDDING_" entries yet EMBEDDING_PROVIDER_TIMEOUT("The Embedding Provider timed out"), EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE("The Embedding Provider returned an unexpected response"), - EMBEDDING_PROVIDER_API_KEY_MISSING("The Embedding Provider API key is missing"), UNSUPPORTED_UPDATE_DATA_TYPE("Unsupported update data type"), diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java index ab09c57e15..230024a4ca 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/gateway/EmbeddingGatewayClient.java @@ -169,7 +169,14 @@ else if (value instanceof Boolean) embeddingResponse = grpcGatewayClient.embed(gatewayRequest); } catch (StatusRuntimeException e) { if (e.getStatus().getCode().equals(Status.Code.DEADLINE_EXCEEDED)) { - throw ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT.toApiException(e, e.getMessage()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_TIMEOUT.get( + Map.of( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(e.getStatus().getCode()), + "errorMessage", + e.getMessage())); } throw e; } diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java index 39d703f248..ef983b6ea9 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java @@ -193,9 +193,14 @@ private Throwable mapBedrockException(BedrockRuntimeException bedrockException) if (bedrockException.statusCode() == Response.Status.REQUEST_TIMEOUT.getStatusCode() || bedrockException.statusCode() == Response.Status.GATEWAY_TIMEOUT.getStatusCode()) { - return ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), bedrockException.statusCode(), bedrockException.getMessage()); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_TIMEOUT.get( + Map.of( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(bedrockException.statusCode()), + "errorMessage", + bedrockException.getMessage())); } if (bedrockException.statusCode() == Response.Status.TOO_MANY_REQUESTS.getStatusCode()) { diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java index 759ce93f85..61013a9c02 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java @@ -1,15 +1,11 @@ package io.stargate.sgv2.jsonapi.service.embedding.operation; import static io.stargate.sgv2.jsonapi.config.constants.HttpConstants.EMBEDDING_AUTHENTICATION_TOKEN_HEADER_NAME; -import static io.stargate.sgv2.jsonapi.exception.ErrorCodeV1.EMBEDDING_PROVIDER_API_KEY_MISSING; import static jakarta.ws.rs.core.Response.Status.Family.CLIENT_ERROR; import io.smallrye.mutiny.Uni; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; -import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; -import io.stargate.sgv2.jsonapi.exception.ServerException; +import io.stargate.sgv2.jsonapi.exception.*; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; import io.stargate.sgv2.jsonapi.service.provider.*; @@ -178,9 +174,12 @@ protected String replaceParameters(String template, Map paramete protected void checkEmbeddingApiKeyHeader(Optional apiKey) { if (apiKey.isEmpty()) { - throw EMBEDDING_PROVIDER_API_KEY_MISSING.toApiException( - "header value `%s` is missing for embedding provider: %s", - EMBEDDING_AUTHENTICATION_TOKEN_HEADER_NAME, modelProvider().apiName()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED.get( + Map.of( + "provider", + modelProvider().apiName(), + "message", + "'%s' header is missing".formatted(EMBEDDING_AUTHENTICATION_TOKEN_HEADER_NAME))); } } @@ -208,8 +207,9 @@ protected int atMostRetries() { protected boolean decideRetry(Throwable throwable) { var retry = - (throwable.getCause() instanceof JsonApiException jae - && jae.getErrorCode() == ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT); + (throwable.getCause() instanceof APIException apiException + && apiException.code.equals( + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_TIMEOUT.name())); return retry || super.decideRetry(throwable); } @@ -220,9 +220,14 @@ protected RuntimeException mapHTTPError(Response jakartaResponse, String errorMe if (jakartaResponse.getStatus() == Response.Status.REQUEST_TIMEOUT.getStatusCode() || jakartaResponse.getStatus() == Response.Status.GATEWAY_TIMEOUT.getStatusCode()) { - return ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_TIMEOUT.get( + Map.of( + "provider", + modelProvider().apiName(), + "httpStatus", + String.valueOf(jakartaResponse.getStatus()), + "errorMessage", + errorMessage)); } // Status code == 429 diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index 606c1449b2..5cbbdbc47d 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2616,5 +2616,9 @@ server-errors: body: |- Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} - + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_TIMEOUT + title: The Embedding Provider request timed out + body: |- + Provider '${provider}' request timed out with HTTP ${httpStatus}; error message: ${errorMessage} diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java index 7fe70e1ea0..2c2f0c77f6 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java @@ -126,7 +126,6 @@ public void test4xx() throws Exception { var exception = vectorizeWithError("400"); assertThat(exception) - .isInstanceOf(EmbeddingProviderException.class) .hasFieldOrPropertyWithValue( "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( @@ -140,7 +139,6 @@ public void test5xx() throws Exception { var exception = vectorizeWithError("503"); assertThat(exception) - .isInstanceOf(EmbeddingProviderException.class) .hasFieldOrPropertyWithValue( "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_SERVER_ERROR.name()) .hasFieldOrPropertyWithValue( @@ -154,11 +152,11 @@ public void testRetryError() throws Exception { var exception = vectorizeWithError("408"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue("errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT) + .hasFieldOrPropertyWithValue( + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_TIMEOUT.name()) .hasFieldOrPropertyWithValue( "message", - "The Embedding Provider timed out: Provider: nvidia; HTTP Status: 408; Error Message: {\"object\":\"list\"}"); + "Provider 'nvidia' request timed out with HTTP 408; error message: {\"object\":\"list\"}"); } @Test diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java index e1fceb7f13..2e75c59295 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java @@ -148,7 +148,6 @@ public void invalidOrg() throws Exception { "some data"); assertThat(exception) - .isInstanceOf(EmbeddingProviderException.class) .hasFieldOrPropertyWithValue( "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( @@ -165,7 +164,6 @@ public void invalidProject() throws Exception { "some data"); assertThat(exception) - .isInstanceOf(EmbeddingProviderException.class) .hasFieldOrPropertyWithValue( "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( From e46aa5a6c656f5043fa90676a5552bee5696b8db Mon Sep 17 00:00:00 2001 From: Hazel Date: Wed, 28 Jan 2026 13:25:08 -0800 Subject: [PATCH 05/14] convert EMBEDDING_PROVIDER_TIMEOUT --- .../io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java | 1 - .../jsonapi/exception/mappers/FrameworkExceptionMapper.java | 6 ------ .../reranking/operation/NvidiaRerankingProvider.java | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 35f309669c..60d1577147 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -6,7 +6,6 @@ public enum ErrorCodeV1 { /** Embedding provider service error codes. */ // !!! 16-Dec-2025, tatu: USED BY EMBEDDING-GATEWAY, DO NOT CONVERT "EMBEDDING_" entries yet - EMBEDDING_PROVIDER_TIMEOUT("The Embedding Provider timed out"), EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE("The Embedding Provider returned an unexpected response"), UNSUPPORTED_UPDATE_DATA_TYPE("Unsupported update data type"), diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/mappers/FrameworkExceptionMapper.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/mappers/FrameworkExceptionMapper.java index 0bfad41c47..7f95ee5e92 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/mappers/FrameworkExceptionMapper.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/mappers/FrameworkExceptionMapper.java @@ -20,7 +20,6 @@ import java.util.Collections; import java.util.Map; import java.util.Optional; -import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.jboss.resteasy.reactive.RestResponse; import org.jboss.resteasy.reactive.server.ServerExceptionMapper; @@ -177,11 +176,6 @@ public static RuntimeException translateThrowable(Throwable throwable) { case APIException ae -> ae; case JsonApiException jae -> jae; - // ########## - // WEIRD ONES FROM throwableToErrorMapper - // TODO: AARON - why would this happen ? was in old ThrowableToErrorMapper - case TimeoutException te -> ErrorCodeV1.EMBEDDING_PROVIDER_TIMEOUT.toApiException(); - // ########## // # QUARKUS ERRORS // these are the client 4xx errors , no change means we return them as-is e.g. the 4XX code diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java index b0432cb32a..1fcd7b35f3 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java @@ -79,7 +79,7 @@ public NvidiaRerankingProvider( nvidiaClient = QuarkusRestClientBuilder.newBuilder() .baseUri(URI.create(modelConfig.url())) - .readTimeout(modelConfig.properties().readTimeoutMillis(), TimeUnit.MILLISECONDS) + .readTimeout(10, TimeUnit.MILLISECONDS) .build(NvidiaRerankingClient.class); } From 36874ac9a1ae428ca4e0134d2e6b16b3267f07d8 Mon Sep 17 00:00:00 2001 From: Hazel Date: Wed, 28 Jan 2026 17:43:53 -0800 Subject: [PATCH 06/14] convert EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE --- .../exception/EmbeddingProviderException.java | 3 +- .../service/embedding/DataVectorizer.java | 79 ++++++++++++------- .../EmbeddingProviderResponseValidation.java | 17 ++-- .../AwsBedrockEmbeddingProvider.java | 12 ++- .../operation/EmbeddingProvider.java | 18 +++-- .../embeddings/EmbeddingDeferredAction.java | 12 +-- src/main/resources/errors.yaml | 6 ++ .../operation/DataVectorizerTest.java | 21 ++--- .../EmbeddingProviderErrorMessageTest.java | 35 +++----- 9 files changed, 110 insertions(+), 93 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 95c950f9d9..1b28f2fd76 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -32,15 +32,14 @@ public EmbeddingProviderException(String code, String title, String body) { public enum Code implements ErrorCode { EMBEDDING_GATEWAY_NOT_AVAILABLE, - EMBEDDING_REQUEST_ENCODING_ERROR, EMBEDDING_RESPONSE_DECODING_ERROR, - EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED, EMBEDDING_PROVIDER_CLIENT_ERROR, EMBEDDING_PROVIDER_RATE_LIMITED, EMBEDDING_PROVIDER_SERVER_ERROR, EMBEDDING_PROVIDER_TIMEOUT, + EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE, ; private final ErrorTemplate template; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/DataVectorizer.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/DataVectorizer.java index f0a5b3213a..8e0c040a53 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/DataVectorizer.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/DataVectorizer.java @@ -2,7 +2,6 @@ import static io.stargate.sgv2.jsonapi.config.constants.DocumentConstants.Fields.VECTOR_EMBEDDING_FIELD; import static io.stargate.sgv2.jsonapi.config.constants.DocumentConstants.Fields.VECTOR_EMBEDDING_TEXT_FIELD; -import static io.stargate.sgv2.jsonapi.exception.ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -125,11 +124,15 @@ public Uni vectorize(List documents) { // check if we get back the same number of vectors that we asked for if (vectorData.size() != vectorizeTexts.size()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' didn't return the expected number of embeddings. Expect: '%d'. Actual: '%d'", - collectionVectorDefinition.vectorizeDefinition().provider(), - vectorizeTexts.size(), - vectorData.size()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE + .get( + Map.of( + "errorMessage", + "Embedding provider '%s' didn't return the expected number of embeddings. Expect: '%d'. Actual: '%d'" + .formatted( + collectionVectorDefinition.vectorizeDefinition().provider(), + vectorizeTexts.size(), + vectorData.size()))); } for (int vectorPosition = 0; vectorPosition < vectorData.size(); @@ -139,11 +142,17 @@ public Uni vectorize(List documents) { float[] vector = vectorData.get(vectorPosition); // check if all vectors have the expected size if (vector.length != collectionVectorDefinition.vectorSize()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'", - collectionVectorDefinition.vectorizeDefinition().provider(), - collectionVectorDefinition.vectorSize(), - vector.length); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE + .get( + Map.of( + "errorMessage", + "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'" + .formatted( + collectionVectorDefinition + .vectorizeDefinition() + .provider(), + collectionVectorDefinition.vectorSize(), + vector.length))); } final ArrayNode arrayNode = nodeFactory.arrayNode(vector.length); for (float listValue : vector) { @@ -194,11 +203,14 @@ public Uni vectorize(String vectorizeContent) { float[] vector = vectorData.get(0); // check if vector have the expected size if (vector.length != collectionVectorDefinition.vectorSize()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'", - collectionVectorDefinition.vectorizeDefinition().provider(), - collectionVectorDefinition.vectorSize(), - vector.length); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'" + .formatted( + collectionVectorDefinition.vectorizeDefinition().provider(), + collectionVectorDefinition.vectorSize(), + vector.length))); } return vector; }); @@ -241,11 +253,15 @@ public Uni vectorize(SortClause sortClause) { vectorConfig.getColumnDefinition(VECTOR_EMBEDDING_TEXT_FIELD).orElseThrow(); // check if vector have the expected size if (vector.length != collectionVectorDefinition.vectorSize()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'", - collectionVectorDefinition.vectorizeDefinition().provider(), - collectionVectorDefinition.vectorSize(), - vector.length); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE + .get( + Map.of( + "errorMessage", + "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'" + .formatted( + collectionVectorDefinition.vectorizeDefinition().provider(), + collectionVectorDefinition.vectorSize(), + vector.length))); } // 12-Jun-2025, tatu: Important! Due to original bad design, we need to allow // replacing of vectorize sort with resolved vector sort: @@ -317,9 +333,11 @@ private Uni> vectorizeTexts( vectorData -> { // Copied from vectorize(List documents) above leaving as is for now if (vectorData.size() != textsToVectorize.size()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' didn't return the expected number of embeddings. Expect: '%d'. Actual: '%d'", - providerName, textsToVectorize.size(), vectorData.size()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Embedding provider '%s' didn't return the expected number of embeddings. Expect: '%d'. Actual: '%d'" + .formatted(providerName, textsToVectorize.size(), vectorData.size()))); } return vectorData; }); @@ -376,11 +394,14 @@ public void setVector(float[] vector) { private void validateVector(float[] vector) { // Copied from vectorize(List documents) above leaving as is for now - aaron if (vector.length != vectorType.getDimension()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'", - vectorType.getVectorizeDefinition().provider(), - vectorType.getDimension(), - vector.length); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'" + .formatted( + vectorType.getVectorizeDefinition().provider(), + vectorType.getDimension(), + vector.length))); } } diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/EmbeddingProviderResponseValidation.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/EmbeddingProviderResponseValidation.java index 034a7a3810..5dc02cae86 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/EmbeddingProviderResponseValidation.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/EmbeddingProviderResponseValidation.java @@ -1,7 +1,6 @@ package io.stargate.sgv2.jsonapi.service.embedding.configuration; -import static io.stargate.sgv2.jsonapi.exception.ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE; - +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.JsonApiException; import jakarta.ws.rs.client.ClientRequestContext; import jakarta.ws.rs.client.ClientResponseContext; @@ -10,6 +9,7 @@ import jakarta.ws.rs.core.Response; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,8 +53,8 @@ public void filter(ClientRequestContext requestContext, ClientResponseContext re // Throw error if there is no response body if (!responseContext.hasEntity()) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "No response body from the embedding provider"); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of("errorMessage", "No response body from the embedding provider")); } // response should always be JSON; if not, error out, include raw response message for @@ -72,9 +72,12 @@ public void filter(ClientRequestContext requestContext, ClientResponseContext re logger.error( "Cannot convert the provider's error response to string: " + e.getMessage(), e); } - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found '%s'; HTTP Status: %s; The response body is: '%s'.", - contentType, responseContext.getStatus(), responseBody); + + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found '%s'; HTTP Status: %s; The response body is: '%s'." + .formatted(contentType, responseContext.getStatus(), responseBody))); } } } diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java index ef983b6ea9..82c959563b 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/AwsBedrockEmbeddingProvider.java @@ -13,7 +13,6 @@ import io.smallrye.mutiny.Uni; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; import io.stargate.sgv2.jsonapi.service.provider.ModelInputType; @@ -235,9 +234,14 @@ private Throwable mapBedrockException(BedrockRuntimeException bedrockException) } // All other errors, Should never happen as all errors are covered above - return ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), bedrockException.statusCode(), bedrockException.getMessage()); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Provider: %s; HTTP Status: %s; Error Message: %s" + .formatted( + modelProvider().apiName(), + bedrockException.statusCode(), + bedrockException.getMessage()))); } private static class ByteUsageTracker { diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java index 61013a9c02..77810f6276 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProvider.java @@ -265,18 +265,20 @@ protected RuntimeException mapHTTPError(Response jakartaResponse, String errorMe } // All other errors, Should never happen as all errors are covered above - return ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage); + return EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Provider: %s; HTTP Status: %s; Error Message: %s" + .formatted(modelProvider().apiName(), jakartaResponse.getStatus(), errorMessage))); } /** Call this from the subclass when the response from the provider is empty */ protected void throwEmptyData(Response jakartaResponse) { - throw ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Provider: %s; HTTP Status: %s; Error Message: %s", - modelProvider().apiName(), - jakartaResponse.getStatus(), - "ModelProvider returned empty data for model %s".formatted(modelName())); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Provider: %s; HTTP Status: %s; Error Message: The embedding provider returned empty data for model %s" + .formatted(modelProvider().apiName(), jakartaResponse.getStatus(), modelName()))); } /** diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/operation/embeddings/EmbeddingDeferredAction.java b/src/main/java/io/stargate/sgv2/jsonapi/service/operation/embeddings/EmbeddingDeferredAction.java index b074dbe9b8..e064d32074 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/operation/embeddings/EmbeddingDeferredAction.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/operation/embeddings/EmbeddingDeferredAction.java @@ -1,12 +1,12 @@ package io.stargate.sgv2.jsonapi.service.operation.embeddings; -import static io.stargate.sgv2.jsonapi.exception.ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE; - +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.VectorizeDefinition; import io.stargate.sgv2.jsonapi.service.schema.tables.ApiVectorType; import io.stargate.sgv2.jsonapi.service.shredding.DeferredAction; import io.stargate.sgv2.jsonapi.util.recordable.PrettyPrintable; import io.stargate.sgv2.jsonapi.util.recordable.Recordable; +import java.util.Map; import java.util.Objects; import java.util.function.Consumer; @@ -94,9 +94,11 @@ private void setFailure(RuntimeException failure) { private void validateVector(float[] vector) { if (vector.length != dimension) { - throw EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.toApiException( - "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'", - vectorizeDefinition.provider(), dimension, vector.length); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.get( + Map.of( + "errorMessage", + "Embedding provider '%s' did not return expected embedding length. Expect: '%d'. Actual: '%d'" + .formatted(vectorizeDefinition.provider(), dimension, vector.length))); } } diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index 5cbbdbc47d..b7bd82dbac 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2622,3 +2622,9 @@ server-errors: body: |- Provider '${provider}' request timed out with HTTP ${httpStatus}; error message: ${errorMessage} + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE + title: The Embedding Provider returned an unexpected response + body: |- + The Embedding Provider returned an unexpected response. + Underlying problem: ${errorMessage}. \ No newline at end of file diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/DataVectorizerTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/DataVectorizerTest.java index 1748773898..7b2b22dfb0 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/DataVectorizerTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/DataVectorizerTest.java @@ -15,10 +15,7 @@ import io.stargate.sgv2.jsonapi.api.model.command.clause.sort.SortExpression; import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; import io.stargate.sgv2.jsonapi.config.constants.DocumentConstants; -import io.stargate.sgv2.jsonapi.exception.DocumentException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; -import io.stargate.sgv2.jsonapi.exception.SchemaException; +import io.stargate.sgv2.jsonapi.exception.*; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.VectorColumnDefinition; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.VectorConfig; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.VectorizeDefinition; @@ -247,12 +244,10 @@ public Uni vectorize( .awaitFailure() .getFailure(); assertThat(failure) - .isInstanceOf(JsonApiException.class) .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) - .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: Embedding provider 'custom' didn't return the expected number of embeddings. Expect: '2'. Actual: '3'"); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining( + "Embedding provider 'custom' didn't return the expected number of embeddings. Expect: '2'. Actual: '3'"); } @Test @@ -291,12 +286,10 @@ public void testWithUnmatchedVectorSize() { .awaitFailure() .getFailure(); assertThat(failure) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: Embedding provider 'custom' did not return expected embedding length. Expect: '4'. Actual: '3'"); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining( + "Embedding provider 'custom' did not return expected embedding length. Expect: '4'. Actual: '3'"); } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java index 2c2f0c77f6..c269a028cf 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java @@ -9,8 +9,6 @@ import io.stargate.sgv2.jsonapi.api.request.EmbeddingCredentials; import io.stargate.sgv2.jsonapi.exception.APIException; import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; -import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfigImpl; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; @@ -185,12 +183,10 @@ public void testIncorrectContentTypeXML() { var exception = vectorizeWithError("application/xml"); assertThat(exception) - .isInstanceOf(JsonApiException.class) .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) - .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found 'application/xml'; HTTP Status: 200; The response body is: 'list'."); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining( + "Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found 'application/xml'; HTTP Status: 200; The response body is: 'list'."); } @Test @@ -199,26 +195,19 @@ public void testIncorrectContentTypePlainText() { var exception = vectorizeWithError("text/plain;charset=UTF-8"); assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found 'text/plain;charset=UTF-8'; HTTP Status: 200; The response body is: 'vectors as plain text'."); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining( + "Expected response Content-Type ('application/json' or 'text/json') from the embedding provider but found 'text/plain;charset=UTF-8'; HTTP Status: 200; The response body is: 'vectors as plain text'."); } @Test public void testNoJsonResponse() { - var exception = vectorizeWithError("no json body"); - assertThat(exception) - .isInstanceOf(JsonApiException.class) - .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: No response body from the embedding provider"); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining("No response body from the embedding provider"); } @Test @@ -227,12 +216,10 @@ public void testEmptyJsonResponse() { var exception = vectorizeWithError("empty json body"); assertThat(exception) - .isInstanceOf(JsonApiException.class) .hasFieldOrPropertyWithValue( - "errorCode", ErrorCodeV1.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE) - .hasFieldOrPropertyWithValue( - "message", - "The Embedding Provider returned an unexpected response: Provider: nvidia; HTTP Status: 200; Error Message: ModelProvider returned empty data for model testModel"); + "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE.name()) + .hasMessageContaining( + "Provider: nvidia; HTTP Status: 200; Error Message: The embedding provider returned empty data for model testModel"); } } } From 42a37e3f9a39324475859bc3344228c97712aa72 Mon Sep 17 00:00:00 2001 From: Hazel Date: Thu, 29 Jan 2026 09:30:18 -0800 Subject: [PATCH 07/14] remove EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE --- .../java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index fc7eff9ac1..2c1504044d 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -6,7 +6,6 @@ public enum ErrorCodeV1 { /** Embedding provider service error codes. */ // !!! 16-Dec-2025, tatu: USED BY EMBEDDING-GATEWAY, DO NOT CONVERT "EMBEDDING_" entries yet - EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE("The Embedding Provider returned an unexpected response"), VECTOR_SEARCH_NOT_SUPPORTED("Vector search is not enabled for the collection"), From 76b453c424abb6709cc6f4fd4080f58e15c1e039 Mon Sep 17 00:00:00 2001 From: Hazel Date: Thu, 29 Jan 2026 11:37:23 -0800 Subject: [PATCH 08/14] remove code used in EGW --- .../exception/EmbeddingProviderException.java | 3 ++ .../sgv2/jsonapi/exception/ErrorCodeV1.java | 7 ++-- .../jsonapi/exception/JsonApiException.java | 8 +---- src/main/resources/errors.yaml | 14 ++++++++ .../exception/JsonApiExceptionTest.java | 32 +++++++++---------- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 1b28f2fd76..363dff8513 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -32,6 +32,9 @@ public EmbeddingProviderException(String code, String title, String body) { public enum Code implements ErrorCode { EMBEDDING_GATEWAY_NOT_AVAILABLE, + EMBEDDING_GATEWAY_REQUEST_PROCESSING_ERROR, + EMBEDDING_GATEWAY_RATE_LIMITED, + EMBEDDING_REQUEST_ENCODING_ERROR, EMBEDDING_RESPONSE_DECODING_ERROR, EMBEDDING_PROVIDER_AUTHENTICATION_KEYS_NOT_PROVIDED, diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 2c1504044d..3d440fd435 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -22,10 +22,11 @@ public enum ErrorCodeV1 { // NOTE: ones used/referenced by `embedding-gateway`, cannot remove: - INVALID_REQUEST("Request not supported by the data store"), +// INVALID_REQUEST("Request not supported by the data store"), - EMBEDDING_GATEWAY_ERROR_RATE_LIMIT("Embedding Gateway error rate limit reached for the tenant"), - EMBEDDING_GATEWAY_PROCESSING_ERROR("Embedding Gateway failed to process request"); +// EMBEDDING_GATEWAY_ERROR_RATE_LIMIT("Embedding Gateway error rate limit reached for the tenant"), +// EMBEDDING_GATEWAY_REQUEST_PROCESSING_ERROR("Embedding Gateway failed to process request"); +; private final String message; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java index d90dc5f65e..e2e4d86091 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java @@ -50,13 +50,7 @@ public class JsonApiException extends RuntimeException { add(VECTOR_SEARCH_TOO_BIG_VALUE); } }, - ErrorScope.SCHEMA, - new HashSet<>() { - { - add(INVALID_REQUEST); - } - }, - ErrorScope.EMBEDDING); + ErrorScope.SCHEMA); protected JsonApiException(ErrorCodeV1 errorCode) { this(errorCode, errorCode.getMessage(), null); diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index 6f8e8b6672..b674e0de2b 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2620,6 +2620,20 @@ server-errors: Embedding Gateway not available. Underlying problem: ${errorMessage}. + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_GATEWAY_REQUEST_PROCESSING_ERROR + title: Embedding Gateway failed to process request + body: |- + Embedding Gateway failed to process request + Underlying problem: ${errorMessage}. + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_GATEWAY_RATE_LIMITED + title: Embedding Gateway rate limited the request + body: |- + Embedding Gateway rate limited the request + Underlying problem: ${errorMessage}. + - scope: EMBEDDING_PROVIDER code: EMBEDDING_REQUEST_ENCODING_ERROR title: Embedding request encoding failure diff --git a/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java b/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java index e5e3152f33..650c592616 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java @@ -1,11 +1,8 @@ package io.stargate.sgv2.jsonapi.exception; -import static org.assertj.core.api.Assertions.assertThat; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; -import io.stargate.sgv2.jsonapi.api.model.command.CommandResult; -import io.stargate.sgv2.jsonapi.api.model.command.tracing.RequestTracing; import io.stargate.sgv2.jsonapi.testresource.NoGlobalResourcesTestProfile; import org.junit.jupiter.api.Test; @@ -16,19 +13,20 @@ class JsonApiExceptionTest { @Test public void happyPath() { - var commandResult = - CommandResult.statusOnlyBuilder(RequestTracing.NO_OP) - .addThrowable(new JsonApiException(ErrorCodeV1.INVALID_REQUEST)) - .build(); - - assertThat(commandResult.data()).isNull(); - assertThat(commandResult.status()).isEmpty(); - assertThat(commandResult.errors()) - .singleElement() - .satisfies( - error -> { - assertThat(error.message()).isEqualTo("Request not supported by the data store"); - assertThat(error.errorCode()).isEqualTo(ErrorCodeV1.INVALID_REQUEST.name()); - }); + // var commandResult = + // CommandResult.statusOnlyBuilder(RequestTracing.NO_OP) + // .addThrowable(new JsonApiException(ErrorCodeV1.INVALID_REQUEST)) + // .build(); + // + // assertThat(commandResult.data()).isNull(); + // assertThat(commandResult.status()).isEmpty(); + // assertThat(commandResult.errors()) + // .singleElement() + // .satisfies( + // error -> { + // assertThat(error.message()).isEqualTo("Request not supported by the data + // store"); + // assertThat(error.errorCode()).isEqualTo(ErrorCodeV1.INVALID_REQUEST.name()); + // }); } } From 34adff3c47228c641ca5f86f004f67e41be57211 Mon Sep 17 00:00:00 2001 From: Hazel Date: Thu, 29 Jan 2026 11:41:57 -0800 Subject: [PATCH 09/14] format --- .../java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java | 2 +- src/main/proto/embedding_gateway.proto | 3 ++- .../stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index 3d440fd435..b26a476026 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -20,7 +20,7 @@ public enum ErrorCodeV1 { VECTORIZE_CREDENTIAL_INVALID("Invalid credential name for vectorize"), - // NOTE: ones used/referenced by `embedding-gateway`, cannot remove: +// NOTE: ones used/referenced by `embedding-gateway`, cannot remove: // INVALID_REQUEST("Request not supported by the data store"), diff --git a/src/main/proto/embedding_gateway.proto b/src/main/proto/embedding_gateway.proto index 06e1ae9099..30f1d62dd8 100644 --- a/src/main/proto/embedding_gateway.proto +++ b/src/main/proto/embedding_gateway.proto @@ -232,7 +232,8 @@ message RerankingResponse { message ErrorResponse { string error_code = 1; - string error_message = 2; + string error_title = 2; + string error_body = 3; } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java b/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java index 650c592616..f3da0b5aca 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/exception/JsonApiExceptionTest.java @@ -1,6 +1,5 @@ package io.stargate.sgv2.jsonapi.exception; - import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; import io.stargate.sgv2.jsonapi.testresource.NoGlobalResourcesTestProfile; From 3f1927893e0df83ae1f6d8914cd6af30a447ce47 Mon Sep 17 00:00:00 2001 From: Hazel Date: Thu, 29 Jan 2026 11:46:50 -0800 Subject: [PATCH 10/14] compile? --- .../jsonapi/service/reranking/gateway/RerankingEGWClient.java | 2 +- .../service/reranking/gateway/RerankingGatewayClientTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingEGWClient.java b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingEGWClient.java index b91f7358be..15dc39deba 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingEGWClient.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingEGWClient.java @@ -99,7 +99,7 @@ public Uni rerank( // 22-Jan-2026, tatu: This is ugly. But has to be done to work around fragility // of exception mapping throw SchemaException.Code.valueOf(gatewayResponse.getError().getErrorCode()) - .withPreformattedMessage(gatewayResponse.getError().getErrorMessage()); + .withPreformattedMessage(gatewayResponse.getError().getErrorBody()); } return new BatchedRerankingResponse( diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingGatewayClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingGatewayClientTest.java index f6d6b7a8f4..7f88c80ef6 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingGatewayClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/reranking/gateway/RerankingGatewayClientTest.java @@ -143,7 +143,7 @@ void handleError() { final SchemaException apiException = SchemaException.Code.RERANKING_PROVIDER_SERVER_ERROR.get( Map.of("errorMessage", "Test fail")); - errorResponseBuilder.setErrorCode(apiException.code).setErrorMessage(apiException.getMessage()); + errorResponseBuilder.setErrorCode(apiException.code).setErrorBody(apiException.getMessage()); builder.setError(errorResponseBuilder.build()); when(rerankService.rerank(any())).thenReturn(Uni.createFrom().item(builder.build())); From 53ec910a78e5a12ef37fa3f1544aefcba66f9405 Mon Sep 17 00:00:00 2001 From: Hazel Date: Fri, 30 Jan 2026 16:11:06 -0800 Subject: [PATCH 11/14] more fixes --- .../exception/EmbeddingProviderException.java | 3 +++ .../sgv2/jsonapi/exception/ErrorCodeV1.java | 12 ++-------- .../jsonapi/exception/JsonApiException.java | 1 - .../operation/EmbeddingProviderFactory.java | 18 +++++++++------ .../service/resolver/ValidateCredentials.java | 2 +- src/main/proto/embedding_gateway.proto | 9 +++++--- src/main/resources/errors.yaml | 23 ++++++++++++++++++- 7 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java index 363dff8513..57a9e5a902 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/EmbeddingProviderException.java @@ -34,6 +34,8 @@ public enum Code implements ErrorCode { EMBEDDING_GATEWAY_NOT_AVAILABLE, EMBEDDING_GATEWAY_REQUEST_PROCESSING_ERROR, EMBEDDING_GATEWAY_RATE_LIMITED, + EMBEDDING_GATEWAY_UNABLE_RESOLVE_AUTHENTICATION_TYPE, + EMBEDDING_GATEWAY_UNEXPECTED_RESPONSE, EMBEDDING_REQUEST_ENCODING_ERROR, EMBEDDING_RESPONSE_DECODING_ERROR, @@ -42,6 +44,7 @@ public enum Code implements ErrorCode { EMBEDDING_PROVIDER_RATE_LIMITED, EMBEDDING_PROVIDER_SERVER_ERROR, EMBEDDING_PROVIDER_TIMEOUT, + EMBEDDING_PROVIDER_UNAVAILABLE, EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE, ; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index b26a476026..f51f22c7c0 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -5,8 +5,6 @@ /** ErrorCode is our internal enum that provides codes and a default message for that error code. */ public enum ErrorCodeV1 { /** Embedding provider service error codes. */ - // !!! 16-Dec-2025, tatu: USED BY EMBEDDING-GATEWAY, DO NOT CONVERT "EMBEDDING_" entries yet - VECTOR_SEARCH_NOT_SUPPORTED("Vector search is not enabled for the collection"), VECTOR_SEARCH_INVALID_FUNCTION_NAME("Invalid vector search function name"), @@ -15,18 +13,12 @@ public enum ErrorCodeV1 { VECTORIZE_FEATURE_NOT_AVAILABLE("Vectorize feature is not available in the environment"), VECTORIZE_SERVICE_NOT_REGISTERED("Vectorize service name provided is not registered : "), + VECTORIZE_SERVICE_TYPE_UNAVAILABLE("Vectorize service unavailable : "), VECTORIZE_INVALID_AUTHENTICATION_TYPE("Invalid vectorize authentication type"), VECTORIZE_CREDENTIAL_INVALID("Invalid credential name for vectorize"), - -// NOTE: ones used/referenced by `embedding-gateway`, cannot remove: - -// INVALID_REQUEST("Request not supported by the data store"), - -// EMBEDDING_GATEWAY_ERROR_RATE_LIMIT("Embedding Gateway error rate limit reached for the tenant"), -// EMBEDDING_GATEWAY_REQUEST_PROCESSING_ERROR("Embedding Gateway failed to process request"); -; + ; private final String message; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java index e2e4d86091..b3b6eb010c 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java @@ -36,7 +36,6 @@ public class JsonApiException extends RuntimeException { add(VECTORIZE_FEATURE_NOT_AVAILABLE); add(VECTORIZE_SERVICE_NOT_REGISTERED); add(VECTORIZE_SERVICE_TYPE_UNAVAILABLE); - add(VECTORIZE_INVALID_AUTHENTICATION_TYPE); add(VECTORIZE_CREDENTIAL_INVALID); } }; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java index 7e1c0ceb5c..509abd3fc0 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java @@ -4,6 +4,7 @@ import io.stargate.embedding.gateway.EmbeddingService; import io.stargate.sgv2.jsonapi.api.request.tenant.Tenant; import io.stargate.sgv2.jsonapi.config.OperationsConfig; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; @@ -84,8 +85,9 @@ public EmbeddingProvider create( ModelProvider.fromApiName(serviceName) .orElseThrow( () -> - ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException( - "unknown service provider '%s'", serviceName)); + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", + "The service provider '%s' is not supported.".formatted(serviceName))); return create( tenant, @@ -150,8 +152,9 @@ public EmbeddingProvider create( EmbeddingProvidersConfig.EmbeddingProviderConfig providerConfig = embeddingProvidersConfig.providers().get(serviceConfig.modelProvider().apiName()); if (providerConfig == null) { - throw ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException( - "unknown service provider '%s'", serviceConfig.modelProvider()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", + "The service provider '%s' is not supported.".formatted(serviceConfig.modelProvider())); } EmbeddingProvidersConfig.EmbeddingProviderConfig.ModelConfig modelConfig = @@ -160,9 +163,10 @@ public EmbeddingProvider create( .findFirst() .orElseThrow( () -> - ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException( - "unknown model '%s' for service provider '%s'", - modelName, serviceConfig.modelProvider())); + EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", + "The model '%s' for service provider '%s' is not supported." + .formatted(modelName, serviceConfig.modelProvider()))); if (operationsConfig.enableEmbeddingGateway()) { return new EmbeddingGatewayClient( diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/resolver/ValidateCredentials.java b/src/main/java/io/stargate/sgv2/jsonapi/service/resolver/ValidateCredentials.java index f846388f9e..c076be0b41 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/resolver/ValidateCredentials.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/resolver/ValidateCredentials.java @@ -40,7 +40,7 @@ public boolean validate(String provider, String value) { embeddingService.validateCredential(validateCredentialRequest.build()); if (validateCredentialResponse.hasError()) { throw ErrorCodeV1.VECTORIZE_CREDENTIAL_INVALID.toApiException( - " with error: %s", validateCredentialResponse.getError().getErrorMessage()); + " with error: %s", validateCredentialResponse.getError().getErrorBody()); } return validateCredentialResponse.getValidity(); } diff --git a/src/main/proto/embedding_gateway.proto b/src/main/proto/embedding_gateway.proto index 30f1d62dd8..51ab52a4b6 100644 --- a/src/main/proto/embedding_gateway.proto +++ b/src/main/proto/embedding_gateway.proto @@ -163,7 +163,8 @@ message GetSupportedProvidersResponse { // The error response message for the embedding gateway gRPC API message ErrorResponse { string error_code = 1; - string error_message = 2; + string error_title = 2; + string error_body = 3; } } @@ -182,7 +183,8 @@ message ValidateCredentialResponse { message Error { string error_code = 1; - string error_message = 2; + string error_title = 2; + string error_body = 3; } } @@ -285,7 +287,8 @@ message GetSupportedRerankingProvidersResponse { message ErrorResponse { string error_code = 1; - string error_message = 2; + string error_title = 2; + string error_body = 3; } } diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index b674e0de2b..45043f79b1 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2632,7 +2632,21 @@ server-errors: title: Embedding Gateway rate limited the request body: |- Embedding Gateway rate limited the request - Underlying problem: ${errorMessage}. + Underlying problem: ${errorMessage}. + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_GATEWAY_UNABLE_RESOLVE_AUTHENTICATION_TYPE + title: Embedding Gateway unable to resolve authentication type + body: |- + Embedding Gateway unable to resolve authentication type. + Underlying problem: ${errorMessage}. + + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_GATEWAY_UNEXPECTED_RESPONSE + title: Embedding Gateway returned an unexpected response. + body: |- + Embedding Gateway returned an unexpected response. + Underlying problem: ${errorMessage}. - scope: EMBEDDING_PROVIDER code: EMBEDDING_REQUEST_ENCODING_ERROR @@ -2678,6 +2692,13 @@ server-errors: body: |- Provider '${provider}' request timed out with HTTP ${httpStatus}; error message: ${errorMessage} + - scope: EMBEDDING_PROVIDER + code: EMBEDDING_PROVIDER_UNAVAILABLE + title: The Embedding Provider is unavailable + body: |- + The Embedding Provider is unavailable + Underlying problem: ${errorMessage} + - scope: EMBEDDING_PROVIDER code: EMBEDDING_PROVIDER_UNEXPECTED_RESPONSE title: The Embedding Provider returned an unexpected response From f5c8b0339321c89f75e71d53222510ed7bf03db0 Mon Sep 17 00:00:00 2001 From: Hazel Date: Mon, 2 Feb 2026 10:31:20 -0800 Subject: [PATCH 12/14] remove VECTORIZE_SERVICE_TYPE_UNAVAILABLE and VECTORIZE_SERVICE_NOT_REGISTERED --- .../stargate/sgv2/jsonapi/exception/ErrorCodeV1.java | 4 ---- .../sgv2/jsonapi/exception/JsonApiException.java | 2 -- .../PropertyBasedServiceConfigStore.java | 6 ++++-- .../operation/EmbeddingProviderFactory.java | 12 ++++++------ .../api/v1/VectorizeSearchIntegrationTest.java | 7 +++++-- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java index f51f22c7c0..32889e5c40 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/ErrorCodeV1.java @@ -12,10 +12,6 @@ public enum ErrorCodeV1 { VECTOR_SEARCH_TOO_BIG_VALUE("Vector embedding property '$vector' length too big"), VECTORIZE_FEATURE_NOT_AVAILABLE("Vectorize feature is not available in the environment"), - VECTORIZE_SERVICE_NOT_REGISTERED("Vectorize service name provided is not registered : "), - - VECTORIZE_SERVICE_TYPE_UNAVAILABLE("Vectorize service unavailable : "), - VECTORIZE_INVALID_AUTHENTICATION_TYPE("Invalid vectorize authentication type"), VECTORIZE_CREDENTIAL_INVALID("Invalid credential name for vectorize"), ; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java index b3b6eb010c..acf04c38f3 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/exception/JsonApiException.java @@ -34,8 +34,6 @@ public class JsonApiException extends RuntimeException { { add(VECTOR_SEARCH_NOT_SUPPORTED); add(VECTORIZE_FEATURE_NOT_AVAILABLE); - add(VECTORIZE_SERVICE_NOT_REGISTERED); - add(VECTORIZE_SERVICE_TYPE_UNAVAILABLE); add(VECTORIZE_CREDENTIAL_INVALID); } }; diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/PropertyBasedServiceConfigStore.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/PropertyBasedServiceConfigStore.java index 51e99a688f..c84d7d21f3 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/PropertyBasedServiceConfigStore.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/configuration/PropertyBasedServiceConfigStore.java @@ -1,6 +1,6 @@ package io.stargate.sgv2.jsonapi.service.embedding.configuration; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.service.provider.ModelProvider; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -44,7 +44,9 @@ public ServiceConfigStore.ServiceConfig getConfiguration(ModelProvider modelProv var providerConfig = providersConfig.providers().get(modelProvider.apiName()); if (providerConfig == null || !providerConfig.enabled()) { - throw ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException(modelProvider.apiName()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", + "The service provider '%s' is not supported.".formatted(modelProvider.apiName())); } Objects.requireNonNull( diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java index 509abd3fc0..0f44f69061 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderFactory.java @@ -5,7 +5,6 @@ import io.stargate.sgv2.jsonapi.api.request.tenant.Tenant; import io.stargate.sgv2.jsonapi.config.OperationsConfig; import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; -import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1; import io.stargate.sgv2.jsonapi.service.embedding.configuration.EmbeddingProvidersConfig; import io.stargate.sgv2.jsonapi.service.embedding.configuration.ServiceConfigStore; import io.stargate.sgv2.jsonapi.service.embedding.gateway.EmbeddingGatewayClient; @@ -136,16 +135,17 @@ public EmbeddingProvider create( // checking this and existing because the rest of the function is validating models etc exist. Optional> clazz = serviceConfig.implementationClass(); if (clazz.isEmpty()) { - throw ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException( - "custom class undefined"); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", "custom class undefined"); } try { return (EmbeddingProvider) clazz.get().getConstructor(int.class).newInstance(dimension); } catch (Exception e) { - throw ErrorCodeV1.VECTORIZE_SERVICE_TYPE_UNAVAILABLE.toApiException( - "custom class provided ('%s') does not resolve to EmbeddingProvider", - clazz.get().getCanonicalName()); + throw EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.get( + "errorMessage", + "custom class provided ('%s') does not resolve to EmbeddingProvider" + .formatted(clazz.get().getCanonicalName())); } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/VectorizeSearchIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/VectorizeSearchIntegrationTest.java index d220e04480..321deab2e8 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/VectorizeSearchIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/VectorizeSearchIntegrationTest.java @@ -9,6 +9,7 @@ import io.quarkus.test.common.WithTestResource; import io.quarkus.test.junit.QuarkusIntegrationTest; import io.stargate.sgv2.jsonapi.exception.DocumentException; +import io.stargate.sgv2.jsonapi.exception.EmbeddingProviderException; import io.stargate.sgv2.jsonapi.exception.SortException; import io.stargate.sgv2.jsonapi.testresource.DseTestResource; import java.util.Arrays; @@ -1159,10 +1160,12 @@ public void findOneAndUpdate_sortClause() { .statusCode(200) .body("$", responseIsError()) .body("errors", hasSize(1)) - .body("errors[0].errorCode", is("VECTORIZE_SERVICE_TYPE_UNAVAILABLE")) + .body( + "errors[0].errorCode", + is(EmbeddingProviderException.Code.EMBEDDING_PROVIDER_UNAVAILABLE.name())) .body( "errors[0].message", - containsString("unknown model 'random' for service provider 'nvidia'")); + containsString("The model 'random' for service provider 'nvidia' is not supported")); } } From f7f726fbbea746e518aa7900940c9587cf8e2523 Mon Sep 17 00:00:00 2001 From: Hazel Date: Mon, 2 Feb 2026 15:10:54 -0800 Subject: [PATCH 13/14] revert NvidiaRerankingProvider change --- .../service/reranking/operation/NvidiaRerankingProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java index 1fcd7b35f3..b0432cb32a 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/reranking/operation/NvidiaRerankingProvider.java @@ -79,7 +79,7 @@ public NvidiaRerankingProvider( nvidiaClient = QuarkusRestClientBuilder.newBuilder() .baseUri(URI.create(modelConfig.url())) - .readTimeout(10, TimeUnit.MILLISECONDS) + .readTimeout(modelConfig.properties().readTimeoutMillis(), TimeUnit.MILLISECONDS) .build(NvidiaRerankingClient.class); } From 385e09d308cc9034df5c26fdcec9caa9f47cceb3 Mon Sep 17 00:00:00 2001 From: Hazel Date: Mon, 2 Feb 2026 15:37:01 -0800 Subject: [PATCH 14/14] use lower-case "error message" --- src/main/resources/errors.yaml | 4 ++-- .../api/v1/tables/InsertOneTableIntegrationTest.java | 10 ++++++---- .../operation/EmbeddingProviderErrorMessageTest.java | 4 ++-- .../embedding/operation/OpenAiEmbeddingClientTest.java | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/resources/errors.yaml b/src/main/resources/errors.yaml index 45043f79b1..525de57707 100644 --- a/src/main/resources/errors.yaml +++ b/src/main/resources/errors.yaml @@ -2672,7 +2672,7 @@ server-errors: code: EMBEDDING_PROVIDER_CLIENT_ERROR title: The Embedding Provider returned a HTTP client error body: |- - Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} + Provider '${provider}' returned a HTTP client error with HTTP ${httpStatus}; error message: ${errorMessage} - scope: EMBEDDING_PROVIDER code: EMBEDDING_PROVIDER_RATE_LIMITED @@ -2684,7 +2684,7 @@ server-errors: code: EMBEDDING_PROVIDER_SERVER_ERROR title: The Embedding Provider returned a HTTP server error body: |- - Provider: ${provider}; HTTP Status: ${httpStatus}; Error Message: ${errorMessage} + Provider '${provider}' returned a HTTP server error with HTTP ${httpStatus}; error message: ${errorMessage} - scope: EMBEDDING_PROVIDER code: EMBEDDING_PROVIDER_TIMEOUT diff --git a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java index 94abeca868..6e34f4d7c8 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/api/v1/tables/InsertOneTableIntegrationTest.java @@ -1736,7 +1736,7 @@ void insertDifferentVectorizeDimensions() { .hasSingleApiError( EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, - "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); + "Provider 'openai' returned a HTTP client error with HTTP 401; error message: \"Incorrect API key provided: test_emb"); } @Order(2) @@ -1785,7 +1785,7 @@ void insertDifferentVectorizeModels() { .hasSingleApiError( EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, - "Provider: openai; HTTP Status: 401; Error Message: \"Incorrect API key provided: test_emb"); + "Provider 'openai' returned a HTTP client error with HTTP 401; error message: \"Incorrect API key provided: test_emb"); } @Order(3) @@ -1834,8 +1834,10 @@ void insertDifferentVectorizeProviders() { EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR, EmbeddingProviderException.class, anyOf( - containsString("Provider: openai; HTTP Status: 401; Error Message: "), - containsString("Provider: jinaAI; HTTP Status: 401; Error Message: "))); + containsString( + "Provider 'openai' returned a HTTP client error with HTTP 401; error message:"), + containsString( + "Provider 'jinaAI' returned a HTTP client error with HTTP 401; error message:"))); } } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java index c269a028cf..a07b2ba825 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/EmbeddingProviderErrorMessageTest.java @@ -128,7 +128,7 @@ public void test4xx() throws Exception { "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "Provider: nvidia; HTTP Status: 400; Error Message: {\"object\":\"list\"}"); + "Provider 'nvidia' returned a HTTP client error with HTTP 400; error message: {\"object\":\"list\"}"); } @Test @@ -141,7 +141,7 @@ public void test5xx() throws Exception { "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_SERVER_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "Provider: nvidia; HTTP Status: 503; Error Message: {\"object\":\"list\"}"); + "Provider 'nvidia' returned a HTTP server error with HTTP 503; error message: {\"object\":\"list\"}"); } @Test diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java index 2e75c59295..1011532cb0 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/embedding/operation/OpenAiEmbeddingClientTest.java @@ -152,7 +152,7 @@ public void invalidOrg() throws Exception { "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); + "Provider 'openai' returned a HTTP client error with HTTP 401; error message: {\"object\":\"list\"}"); } @Test @@ -168,7 +168,7 @@ public void invalidProject() throws Exception { "code", EmbeddingProviderException.Code.EMBEDDING_PROVIDER_CLIENT_ERROR.name()) .hasFieldOrPropertyWithValue( "message", - "Provider: openai; HTTP Status: 401; Error Message: {\"object\":\"list\"}"); + "Provider 'openai' returned a HTTP client error with HTTP 401; error message: {\"object\":\"list\"}"); } } }