Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ public DatabaseException(ErrorInstance errorInstance) {
}

public enum Code implements ErrorCode<DatabaseException> {
COUNT_READ_FAILED, // converted from ErrorV1
COLLECTION_NO_INDEX_ERROR, // converted from ErrorCodeV1.NO_INDEX_ERROR
COLLECTION_SCHEMA_VERSION_INVALID, // converted from ErrorCodeV1.INVALID_SCHEMA_VERSION
COUNT_READ_FAILED, // converted from ErrorCodeV1
DOCUMENT_FROM_DB_UNPARSEABLE,
FAILED_CONCURRENT_OPERATIONS,
FAILED_COMPARE_AND_SET,
FAILED_READ_REQUEST,
FAILED_TO_CONNECT_TO_DATABASE,
FAILED_TRUNCATION,
FAILED_WRITE_REQUEST,
INVALID_COLLECTION_QUERY, // legacy: converted from ErrorCodeV1.INVALID_QUERY
INVALID_DATABASE_QUERY,
TIMEOUT_READING_DATA,
TIMEOUT_WRITING_DATA,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public DocumentException(ErrorInstance errorInstance) {
}

public enum Code implements ErrorCode<DocumentException> {
DOCUMENT_ALREADY_EXISTS,
DOCUMENT_ALREADY_EXISTS, // converted from ErrorCodeV1 -- in use by client DO NOT RENAME
DOCUMENT_LEXICAL_CONTENT_TOO_BIG,
DOCUMENT_REPLACE_DIFFERENT_DOCID,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public enum ErrorCodeV1 {

// CreateCollection error codes:

EXISTING_TABLE_NOT_DATA_API_COLLECTION("Existing table is not a valid Data API collection"),
COLLECTION_CREATION_ERROR(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cannot yet convert this one due to the way it is returned (not throw) in CreateCollectionOperation, handle after @amorton's refactoring of DB access.

"Collection creation failure (unable to create table). Recommend re-creating the collection"),
EMBEDDING_SERVICE_NOT_CONFIGURED(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved next to related codes; to be converted in follow-up PR.

"Unable to vectorize data, embedding service not configured for the collection "),
INDEXES_CREATION_FAILED("Index creation failed, check schema"),
INVALID_INDEXING_DEFINITION("Invalid indexing definition"),
INVALID_JSONAPI_COLLECTION_SCHEMA("Not a valid json api collection schema"),
Expand All @@ -46,8 +49,6 @@ public enum ErrorCodeV1 {
UNSUPPORTED_UPDATE_DATA_TYPE("Unsupported update data type"),

UNSUPPORTED_UPDATE_OPERATION("Unsupported update operation"),
EMBEDDING_SERVICE_NOT_CONFIGURED(
"Unable to vectorize data, embedding service not configured for the collection "),

UNSUPPORTED_UPDATE_OPERATION_MODIFIER("Unsupported update operation modifier"),

Expand Down Expand Up @@ -81,13 +82,6 @@ public enum ErrorCodeV1 {
HYBRID_FIELD_UNSUPPORTED_SUBFIELD_VALUE_TYPE(
"Unsupported JSON value type for '$hybrid' sub-field"),

COLLECTION_CREATION_ERROR(
"Collection creation failure (unable to create table). Recommend re-creating the collection"),
INVALID_SCHEMA_VERSION(
"Collection has invalid schema version. Recommend re-creating the collection"),
INVALID_QUERY("Invalid query"),
NO_INDEX_ERROR("Faulty collection (missing indexes). Recommend re-creating the collection"),

// Driver failure codes
/** Error codes related to driver exceptions. */
SERVER_CLOSED_CONNECTION("Driver request connection is closed"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ public class JsonApiException extends RuntimeException implements Supplier<Comma
add(VECTORIZE_INVALID_AUTHENTICATION_TYPE);
add(VECTORIZE_CREDENTIAL_INVALID);
add(VECTORIZECONFIG_CHECK_FAIL);
add(COLLECTION_CREATION_ERROR);
add(INVALID_QUERY);
add(NO_INDEX_ERROR);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ public enum Code implements ErrorCode<SchemaException> {
CANNOT_RENAME_UNKNOWN_TYPE_FIELD,
CANNOT_VECTORIZE_NON_VECTOR_COLUMNS,
CANNOT_VECTORIZE_UNKNOWN_COLUMNS,
COLLECTION_EXISTS_WITH_DIFFERENT_SETTINGS, // converted from ErrorCodeV1
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

renaming undone: changed back to EXISTING_COLLECTION_DIFFERENT_SETTINGS for compatibility reasons.

COLLECTION_NOT_EXIST, // converted from ErrorCodeV1
DEPRECATED_AI_MODEL,
END_OF_LIFE_AI_MODEL,

// from ErrorCodeV1 but used by clients DO NOT RENAME:
EXISTING_COLLECTION_DIFFERENT_SETTINGS,
EXISTING_TABLE_NOT_DATA_API_COLLECTION, // converted from ErrorCodeV1
INVALID_CREATE_COLLECTION_OPTIONS,
INVALID_FORMAT_FOR_INDEX_CREATION_COLUMN,
INVALID_USER_DEFINED_TYPE_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,10 @@ private static CommandResult.Error handleQueryValidationException(
} else if (message.contains(
"If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING")
|| message.contains("ANN ordering by vector requires the column to be indexed")) {
return ErrorCodeV1.NO_INDEX_ERROR
.toApiException()
.getCommandResultError(ErrorCodeV1.NO_INDEX_ERROR.getMessage(), Response.Status.OK);
// Alas: Collection name not available at this point:
return DatabaseException.Code.COLLECTION_NO_INDEX_ERROR
.get()
.getCommandResultError(Response.Status.OK);
}
if (message.contains("vector<float,")) {
// It is tricky to find the actual vector dimension from the message, include as-is
Expand All @@ -194,9 +195,9 @@ private static CommandResult.Error handleQueryValidationException(
.get()
.getCommandResultError(Response.Status.OK);
}
return ErrorCodeV1.INVALID_QUERY
.toApiException()
.getCommandResultError(message, Response.Status.OK);
return DatabaseException.Code.INVALID_COLLECTION_QUERY
.get(Map.of("errorMessage", message))
.getCommandResultError(Response.Status.OK);
}

/** Driver AllNodesFailedException a composite exception, peeling the errors from it */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ public Uni<Supplier<CommandResult>> execute(
}
return Uni.createFrom()
.failure(
SchemaException.Code.COLLECTION_EXISTS_WITH_DIFFERENT_SETTINGS.get(
Map.of("collection", name)));
SchemaException.Code.EXISTING_COLLECTION_DIFFERENT_SETTINGS.get(
Map.of("collectionName", name)));
});
}

Expand Down Expand Up @@ -452,8 +452,8 @@ TableMetadata findTableAndValidateLimits(
if (table.getName().asInternal().equals(tableName)) {
// If that is not a valid Data API collection, error out the createCollectionCommand
if (!COLLECTION_MATCHER.test(table)) {
throw ErrorCodeV1.EXISTING_TABLE_NOT_DATA_API_COLLECTION.toApiException(
"table ('%s') already exists and it is not a valid Data API collection", tableName);
throw SchemaException.Code.EXISTING_TABLE_NOT_DATA_API_COLLECTION.get(
Map.of("tableName", tableName));
}
// If that is a valid Data API table, we returned it
return table;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import io.stargate.sgv2.jsonapi.config.constants.DocumentConstants;
import io.stargate.sgv2.jsonapi.config.constants.TableCommentConstants;
import io.stargate.sgv2.jsonapi.config.constants.VectorConstants;
import io.stargate.sgv2.jsonapi.exception.ErrorCodeV1;
import io.stargate.sgv2.jsonapi.exception.DatabaseException;
import io.stargate.sgv2.jsonapi.exception.ServerException;
import io.stargate.sgv2.jsonapi.service.cqldriver.executor.*;
import io.stargate.sgv2.jsonapi.service.projection.IndexingProjector;
Expand Down Expand Up @@ -335,15 +335,22 @@ private static CollectionSchemaObject createCollectionSettings(
final JsonNode schemaVersionNode =
collectionNode.get(TableCommentConstants.SCHEMA_VERSION_KEY);
if (schemaVersionNode == null) {
throw ErrorCodeV1.INVALID_SCHEMA_VERSION.toApiException();
throw DatabaseException.Code.COLLECTION_SCHEMA_VERSION_INVALID.get(
Map.of("collectionName", collectionName, "schemaVersion", "<null>"));
}
switch (collectionNode.get(TableCommentConstants.SCHEMA_VERSION_KEY).asInt()) {
int schemaVersion = collectionNode.get(TableCommentConstants.SCHEMA_VERSION_KEY).asInt();
switch (schemaVersion) {
case 1:
return new CollectionSettingsV1Reader()
.readCollectionSettings(
collectionNode, keyspaceName, collectionName, tableMetadata, objectMapper);
default:
throw ErrorCodeV1.INVALID_SCHEMA_VERSION.toApiException();
throw DatabaseException.Code.COLLECTION_SCHEMA_VERSION_INVALID.get(
Map.of(
"collectionName",
collectionName,
"schemaVersion",
String.valueOf(schemaVersion)));
}
} else {
// backward compatibility for old indexing table comment
Expand Down
106 changes: 71 additions & 35 deletions src/main/resources/errors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#
# "snippets" is a list of text snippets than can be included in any error body, the snippets are included in the
# variables when running the template for the body of the error. Snippets are referenced using `${SNIPET.<NAME>}`
# variables when running the template for the body of the error. Snippets are referenced using `${SNIPET.<NAME>}`
# where <NAME> is the name of the snippet key.
# Each snippet has:
# - name: UPPER_SNAKE_CASE_1
Expand Down Expand Up @@ -1181,17 +1182,9 @@ request-errors:

Resend the command without dropping the indexed columns.

- scope: SCHEMA
code: COLLECTION_EXISTS_WITH_DIFFERENT_SETTINGS
title: Collection or table does not exist
body: |-
Collection '${collection}' already exists but with settings different from ones passed with 'createCollection' command.

If you need to change collection settings you will need to 'deleteCollection', then re-create with new settings.

- scope: SCHEMA
code: COLLECTION_NOT_EXIST
title: Collection already exists with different settings
title: Collection or table does not exist
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed an earlier copy-paste problem.

body: |-
No collection or table with name '${collection}' exists.

Expand All @@ -1217,6 +1210,22 @@ request-errors:

Resend the command using supported model.

- scope: SCHEMA
code: EXISTING_COLLECTION_DIFFERENT_SETTINGS
title: Collection already exists with different settings
body: |-
Collection '${collectionName}' already exists but with settings different from ones passed with 'createCollection' command.

If you need to change collection settings you will need to 'deleteCollection', then re-create with new settings.

- scope: SCHEMA
code: EXISTING_TABLE_NOT_DATA_API_COLLECTION
title: Existing table not a valid Data API collection
body: |-
Attempt to create new collection failed: table '${tableName}' already exists and it is not a valid Data API collection.

Recommend deleting the table and resending the command.

- scope: SCHEMA
code: CANNOT_VECTORIZE_UNKNOWN_COLUMNS
title: Columns cannot be vectorized if they are not defined in the table schema
Expand Down Expand Up @@ -2062,6 +2071,24 @@ server-errors:

# DATABASE scope server errors

- scope: DATABASE
code: COLLECTION_NO_INDEX_ERROR
title: Collection missing index(es)
body: |-
Faulty collection (missing index(es)).
Recommend re-creating the collection.

${SNIPPET.RETRY_UNKNOWN}

- scope: DATABASE
code: COLLECTION_SCHEMA_VERSION_INVALID
title: Collection schema version invalid
body: |-
Collection '${collectionName}' has invalid schema version (${schemaVersion}).
Recommend re-creating the collection.

${SNIPPET.RETRY_UNKNOWN}

- scope: DATABASE
code: COUNT_READ_FAILED
title: Count read failed
Expand All @@ -2081,6 +2108,41 @@ server-errors:

Report the problem to database administrators.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These were moved to alphabetic position, not changed in any way.

- scope: DATABASE
code: FAILED_CONCURRENT_OPERATIONS
title: Failed to complete concurrent operations on the database
body: |-
The Data API command was unable to complete an operation on a document or row due to concurrent modifications from other requests.

This should be a rare error, it occurs when multiple requests attempt to modify the same document or row at the same time. The Data API has retried the operation multiple times, but was unable to complete it before another request modified the same document or row. This may indicate a "hot row" in your database, or low resources slowing down the database.

NOTE: If the request updated multiple documents or rows, some of the updates may have completed successfully. Check the response for partial success information.

The command used the keyspace and table or collection: ${keyspace}.${table}.

${SNIPPET.RETRY}

- scope: DATABASE
code: FAILED_TO_CONNECT_TO_DATABASE
title: Data API Failed to connect to the database
body: |-
The Data API was unable to connect to any nodes in the database to process the command.

This may be due to a temporary capacity issue with the database, or a wider outage.

The command used the keyspace and table or collection: ${keyspace}.${table}.

${SNIPPET.RETRY}

- scope: DATABASE
code: INVALID_COLLECTION_QUERY
Copy link
Copy Markdown
Contributor Author

@tatu-at-datastax tatu-at-datastax Jan 8, 2026

Choose a reason for hiding this comment

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

Renamed from INVALID_QUERY, but usage should probably be eventually unified with INVALID_DATABASE_QUERY as part of query handling changes.

title: Invalid query
body: |-
Invalid query against a collection.
Underlying problem: ${errorMessage}.

${SNIPPET.RETRY_UNKNOWN}

- scope: DATABASE
code: UNEXPECTED_DOCUMENT_ID_TYPE
title: Unexpected stored document id type
Expand Down Expand Up @@ -2120,18 +2182,6 @@ server-errors:

${SNIPPET.RETRY}

- scope: DATABASE
code: FAILED_TO_CONNECT_TO_DATABASE
title: Data API Failed to connect to the database
body: |-
The Data API was unable to connect to any nodes in the database to process the command.

This may be due to a temporary capacity issue with the database, or a wider outage.

The command used the keyspace and table or collection: ${keyspace}.${table}.

${SNIPPET.RETRY}

- scope: DATABASE
code: UNAUTHORIZED_ACCESS
title: Unauthorized access to the database
Expand Down Expand Up @@ -2174,20 +2224,6 @@ server-errors:

Retrying the command will likely result in the same error.

- scope: DATABASE
code: FAILED_CONCURRENT_OPERATIONS
title: Failed to complete concurrent operations on the database
body: |-
The Data API command was unable to complete an operation on a document or row due to concurrent modifications from other requests.

This should be a rare error, it occurs when multiple requests attempt to modify the same document or row at the same time. The Data API has retried the operation multiple times, but was unable to complete it before another request modified the same document or row. This may indicate a "hot row" in your database, or low resources slowing down the database.

NOTE: If the request updated multiple documents or rows, some of the updates may have completed successfully. Check the response for partial success information.

The command used the keyspace and table or collection: ${keyspace}.${table}.

${SNIPPET.RETRY}

- scope: DATABASE
code: FAILED_COMPARE_AND_SET
title: Failed database Compare and Set operation
Expand Down
Loading