Skip to content

Commit 10d2be6

Browse files
committed
Merge branch 'master' into feature/error_handling_athena_federation_sdk
2 parents 2551e72 + c65b448 commit 10d2be6

File tree

27 files changed

+162
-65
lines changed

27 files changed

+162
-65
lines changed

.github/workflows/javadoc_sync.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
run: rm -rf com
2929

3030
- name: Copy new files
31-
run: cp -r target/site/apidocs/* .
31+
run: cp -r target/reports/apidocs/* .
3232

3333
- name: Commit files
3434
run: |

athena-dynamodb/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<dependency>
1414
<groupId>software.amazon.awssdk</groupId>
1515
<artifactId>bom</artifactId>
16-
<version>2.28.1</version>
16+
<version>2.28.21</version>
1717
<type>pom</type>
1818
<scope>import</scope>
1919
</dependency>

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/DynamoDBMetadataHandler.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.amazonaws.athena.connector.lambda.domain.TableName;
3030
import com.amazonaws.athena.connector.lambda.domain.predicate.ValueSet;
3131
import com.amazonaws.athena.connector.lambda.domain.spill.SpillLocation;
32+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
3233
import com.amazonaws.athena.connector.lambda.handlers.GlueMetadataHandler;
3334
import com.amazonaws.athena.connector.lambda.metadata.GetDataSourceCapabilitiesRequest;
3435
import com.amazonaws.athena.connector.lambda.metadata.GetDataSourceCapabilitiesResponse;
@@ -59,6 +60,8 @@
5960
import com.amazonaws.services.athena.AmazonAthena;
6061
import com.amazonaws.services.glue.AWSGlue;
6162
import com.amazonaws.services.glue.model.Database;
63+
import com.amazonaws.services.glue.model.ErrorDetails;
64+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
6265
import com.amazonaws.services.glue.model.Table;
6366
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
6467
import com.amazonaws.util.json.Jackson;
@@ -255,7 +258,7 @@ public ListTablesResponse doListTables(BlockAllocator allocator, ListTablesReque
255258
public GetTableResponse doGetQueryPassthroughSchema(BlockAllocator allocator, GetTableRequest request) throws Exception
256259
{
257260
if (!request.isQueryPassthrough()) {
258-
throw new IllegalArgumentException("No Query passed through [{}]" + request);
261+
throw new AthenaConnectorException("No Query passed through [{}]" + request, new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()).withErrorMessage("No Query passed through [{}]" + request));
259262
}
260263

261264
queryPassthrough.verify(request.getQueryPassthroughArguments());
@@ -324,7 +327,7 @@ public void enhancePartitionSchema(SchemaBuilder partitionSchemaBuilder, GetTabl
324327
table = tableResolver.getTableMetadata(tableName);
325328
}
326329
catch (TimeoutException e) {
327-
throw new RuntimeException(e);
330+
throw new AthenaConnectorException(e.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.OperationTimeoutException.toString()).withErrorMessage(e.getMessage()));
328331
}
329332
// add table name so we don't have to do case insensitive resolution again
330333
partitionSchemaBuilder.addMetadata(TABLE_METADATA, table.getName());
@@ -471,7 +474,7 @@ public GetSplitsResponse doGetSplits(BlockAllocator allocator, GetSplitsRequest
471474
Map<String, String> partitionMetadata = partitions.getSchema().getCustomMetadata();
472475
String partitionType = partitionMetadata.get(PARTITION_TYPE_METADATA);
473476
if (partitionType == null) {
474-
throw new IllegalStateException(String.format("No metadata %s defined in Schema %s", PARTITION_TYPE_METADATA, partitions.getSchema()));
477+
throw new AthenaConnectorException(String.format("No metadata %s defined in Schema %s", PARTITION_TYPE_METADATA, partitions.getSchema()), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
475478
}
476479
if (QUERY_PARTITION_TYPE.equals(partitionType)) {
477480
String hashKeyName = partitionMetadata.get(HASH_KEY_NAME_METADATA);
@@ -527,7 +530,7 @@ else if (SCAN_PARTITION_TYPE.equals(partitionType)) {
527530
return new GetSplitsResponse(request.getCatalogName(), splits, null);
528531
}
529532
else {
530-
throw new IllegalStateException("Unexpected partition type " + partitionType);
533+
throw new AthenaConnectorException("Unexpected partition type " + partitionType, new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
531534
}
532535
}
533536

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/DynamoDBRecordHandler.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.amazonaws.athena.connector.lambda.data.writers.extractors.Extractor;
2828
import com.amazonaws.athena.connector.lambda.domain.Split;
2929
import com.amazonaws.athena.connector.lambda.domain.predicate.Constraints;
30+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
3031
import com.amazonaws.athena.connector.lambda.handlers.RecordHandler;
3132
import com.amazonaws.athena.connector.lambda.records.ReadRecordsRequest;
3233
import com.amazonaws.athena.connectors.dynamodb.credentials.CrossAccountCredentialsProviderV2;
@@ -36,6 +37,8 @@
3637
import com.amazonaws.athena.connectors.dynamodb.util.DDBRecordMetadata;
3738
import com.amazonaws.athena.connectors.dynamodb.util.DDBTypeUtils;
3839
import com.amazonaws.services.athena.AmazonAthena;
40+
import com.amazonaws.services.glue.model.ErrorDetails;
41+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
3942
import com.amazonaws.services.s3.AmazonS3;
4043
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
4144
import com.amazonaws.util.json.Jackson;
@@ -206,7 +209,7 @@ protected void readWithConstraint(BlockSpiller spiller, ReadRecordsRequest recor
206209
private void handleQueryPassthroughPartiQLQuery(BlockSpiller spiller, ReadRecordsRequest recordsRequest, QueryStatusChecker queryStatusChecker)
207210
{
208211
if (!recordsRequest.getConstraints().isQueryPassThrough()) {
209-
throw new RuntimeException("Attempting to readConstraints with Query Passthrough without PartiQL Query");
212+
throw new AthenaConnectorException("Attempting to readConstraints with Query Passthrough without PartiQL Query", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
210213
}
211214
queryPassthrough.verify(recordsRequest.getConstraints().getQueryPassthroughArguments());
212215

@@ -325,7 +328,7 @@ private QueryRequest buildQueryRequest(Split split, String tableName, Schema sch
325328
expressionAttributeValues.putAll(EnhancedDocument.fromJson(split.getProperty(EXPRESSION_VALUES_METADATA)).toMap());
326329
}
327330
catch (IOException e) {
328-
throw new RuntimeException(e);
331+
throw new AthenaConnectorException(e.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InternalServiceException.toString()));
329332
}
330333
}
331334

@@ -392,7 +395,7 @@ private ScanRequest buildScanRequest(Split split, String tableName, Schema schem
392395
expressionAttributeValues.putAll(EnhancedDocument.fromJson(split.getProperty(EXPRESSION_VALUES_METADATA)).toMap());
393396
}
394397
catch (IOException e) {
395-
throw new RuntimeException(e);
398+
throw new AthenaConnectorException(e.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InternalServiceException.toString()));
396399
}
397400
}
398401

@@ -465,7 +468,7 @@ public Map<String, AttributeValue> next()
465468
}
466469
}
467470
catch (TimeoutException | ExecutionException e) {
468-
throw new RuntimeException(e);
471+
throw new AthenaConnectorException(e.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.OperationTimeoutException.toString()));
469472
}
470473
currentPageIterator.set(iterator);
471474
if (iterator.hasNext()) {

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/qpt/DDBQueryPassthrough.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
*/
2020
package com.amazonaws.athena.connectors.dynamodb.qpt;
2121

22+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2223
import com.amazonaws.athena.connector.lambda.metadata.optimizations.querypassthrough.QueryPassthroughSignature;
24+
import com.amazonaws.services.glue.model.ErrorDetails;
25+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
2326
import com.google.common.collect.ImmutableSet;
2427
import org.slf4j.Logger;
2528
import org.slf4j.LoggerFactory;
@@ -77,7 +80,7 @@ public void customConnectorVerifications(Map<String, String> engineQptArguments)
7780

7881
// Immediately check if the statement starts with "SELECT"
7982
if (!upperCaseStatement.startsWith("SELECT")) {
80-
throw new UnsupportedOperationException("Statement does not start with SELECT.");
83+
throw new AthenaConnectorException("Statement does not start with SELECT.", new ErrorDetails().withErrorCode(FederationSourceErrorCode.OperationNotSupportedException.toString()));
8184
}
8285

8386
// List of disallowed keywords
@@ -86,7 +89,7 @@ public void customConnectorVerifications(Map<String, String> engineQptArguments)
8689
// Check if the statement contains any disallowed keywords
8790
for (String keyword : disallowedKeywords) {
8891
if (upperCaseStatement.contains(keyword)) {
89-
throw new UnsupportedOperationException("Unaccepted operation; only SELECT statements are allowed. Found: " + keyword);
92+
throw new AthenaConnectorException("Unaccepted operation; only SELECT statements are allowed. Found: " + keyword, new ErrorDetails().withErrorCode(FederationSourceErrorCode.OperationNotSupportedException.toString()));
9093
}
9194
}
9295
}

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/resolver/DynamoDBFieldResolver.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
package com.amazonaws.athena.connectors.dynamodb.resolver;
2121

2222
import com.amazonaws.athena.connector.lambda.data.FieldResolver;
23+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2324
import com.amazonaws.athena.connectors.dynamodb.util.DDBRecordMetadata;
2425
import com.amazonaws.athena.connectors.dynamodb.util.DDBTypeUtils;
26+
import com.amazonaws.services.glue.model.ErrorDetails;
27+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
2528
import org.apache.arrow.vector.types.Types;
2629
import org.apache.arrow.vector.types.pojo.Field;
2730
import org.slf4j.Logger;
@@ -86,8 +89,8 @@ public Object getFieldValue(Field field, Object originalValue)
8689
return DDBTypeUtils.coerceValueToExpectedType(fieldValue, field, fieldType, metadata);
8790
}
8891

89-
throw new RuntimeException("Invalid field value encountered in DB record for field: " + field +
90-
",value: " + fieldValue);
92+
throw new AthenaConnectorException("Invalid field value encountered in DB record for field: " + field +
93+
",value: " + fieldValue, new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
9194
}
9295

9396
// Return the field value of a map key

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/resolver/DynamoDBTableResolver.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
package com.amazonaws.athena.connectors.dynamodb.resolver;
2121

2222
import com.amazonaws.athena.connector.lambda.ThrottlingInvoker;
23+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2324
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBPaginatedTables;
2425
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBTable;
2526
import com.amazonaws.athena.connectors.dynamodb.util.DDBTableUtils;
27+
import com.amazonaws.services.glue.model.ErrorDetails;
28+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
2629
import com.google.common.collect.ArrayListMultimap;
2730
import com.google.common.collect.Multimap;
2831
import org.apache.arrow.vector.types.pojo.Schema;
@@ -118,7 +121,7 @@ public Schema getTableSchema(String tableName)
118121
return DDBTableUtils.peekTableForSchema(caseInsensitiveMatch.get(), invoker, ddbClient);
119122
}
120123
else {
121-
throw e;
124+
throw new AthenaConnectorException(e.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.EntityNotFoundException.toString()));
122125
}
123126
}
124127
}

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/util/DDBPredicateUtils.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
import com.amazonaws.athena.connector.lambda.domain.predicate.Range;
2525
import com.amazonaws.athena.connector.lambda.domain.predicate.SortedRangeSet;
2626
import com.amazonaws.athena.connector.lambda.domain.predicate.ValueSet;
27+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2728
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBIndex;
2829
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBTable;
30+
import com.amazonaws.services.glue.model.ErrorDetails;
31+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
2932
import com.google.common.base.Joiner;
3033
import com.google.common.collect.ImmutableList;
3134
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
@@ -189,15 +192,15 @@ private static void validateColumnRange(Range range)
189192
case EXACTLY:
190193
break;
191194
case BELOW:
192-
throw new IllegalArgumentException("Low marker should never use BELOW bound");
195+
throw new AthenaConnectorException("Low marker should never use BELOW bound", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
193196
default:
194197
throw new AssertionError("Unhandled lower bound: " + range.getLow().getBound());
195198
}
196199
}
197200
if (!range.getHigh().isUpperUnbounded()) {
198201
switch (range.getHigh().getBound()) {
199202
case ABOVE:
200-
throw new IllegalArgumentException("High marker should never use ABOVE bound");
203+
throw new AthenaConnectorException("High marker should never use ABOVE bound", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
201204
case EXACTLY:
202205
break;
203206
case BELOW:

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/util/DDBTableUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121

2222
import com.amazonaws.athena.connector.lambda.ThrottlingInvoker;
2323
import com.amazonaws.athena.connector.lambda.data.SchemaBuilder;
24+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
2425
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBIndex;
2526
import com.amazonaws.athena.connectors.dynamodb.model.DynamoDBTable;
27+
import com.amazonaws.services.glue.model.ErrorDetails;
28+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
2629
import com.google.common.collect.ImmutableList;
2730
import org.apache.arrow.vector.types.pojo.Schema;
2831
import org.slf4j.Logger;
@@ -167,7 +170,7 @@ public static Schema peekTableForSchema(String tableName, ThrottlingInvoker invo
167170
logger.warn("Failed to retrieve table schema due to KMS issue, empty schema for table: {}. Error Message: {}", tableName, runtimeException.getMessage());
168171
}
169172
else {
170-
throw runtimeException;
173+
throw new AthenaConnectorException(runtimeException.getMessage(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.OperationTimeoutException.toString()));
171174
}
172175
}
173176
return schemaBuilder.build();

athena-dynamodb/src/main/java/com/amazonaws/athena/connectors/dynamodb/util/DDBTypeUtils.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
import com.amazonaws.athena.connector.lambda.data.writers.holders.NullableDecimalHolder;
3131
import com.amazonaws.athena.connector.lambda.data.writers.holders.NullableVarBinaryHolder;
3232
import com.amazonaws.athena.connector.lambda.domain.predicate.ConstraintProjector;
33+
import com.amazonaws.athena.connector.lambda.exceptions.AthenaConnectorException;
3334
import com.amazonaws.athena.connectors.dynamodb.resolver.DynamoDBFieldResolver;
35+
import com.amazonaws.services.glue.model.ErrorDetails;
36+
import com.amazonaws.services.glue.model.FederationSourceErrorCode;
3437
import org.apache.arrow.vector.FieldVector;
3538
import org.apache.arrow.vector.holders.NullableBitHolder;
3639
import org.apache.arrow.vector.types.Types;
@@ -188,7 +191,7 @@ else if (enhancedAttributeValue.isMap()) {
188191
}
189192

190193
String attributeTypeName = (value == null || value.getClass() == null) ? "null" : enhancedAttributeValue.type().name();
191-
throw new RuntimeException("Unknown Attribute Value Type[" + attributeTypeName + "] for field[" + key + "]");
194+
throw new AthenaConnectorException("Unknown Attribute Value Type[" + attributeTypeName + "] for field[" + key + "]", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
192195
}
193196

194197
/**
@@ -262,7 +265,7 @@ public static Field getArrowFieldFromDDBType(String attributeName, String attrib
262265
case MAP:
263266
return new Field(attributeName, FieldType.nullable(Types.MinorType.STRUCT.getType()), null);
264267
default:
265-
throw new RuntimeException("Unknown type[" + attributeType + "] for field[" + attributeName + "]");
268+
throw new AthenaConnectorException("Unknown type[" + attributeType + "] for field[" + attributeName + "]", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
266269
}
267270
}
268271

@@ -382,7 +385,7 @@ public static List<Object> coerceListToExpectedType(Object value, Field field, D
382385

383386
if (!(value instanceof Collection)) {
384387
if (value instanceof Map) {
385-
throw new RuntimeException("Unexpected type (Map) encountered for: " + childField.getName());
388+
throw new AthenaConnectorException("Unexpected type (Map) encountered for: " + childField.getName(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
386389
}
387390
return Collections.singletonList(coerceValueToExpectedType(value, childField, fieldType, recordMetadata));
388391
}
@@ -618,7 +621,7 @@ else if (value instanceof Map<?, ?>) {
618621
return handleMapType((Map<String, Object>) value);
619622
}
620623
else {
621-
throw new UnsupportedOperationException("Unsupported value type: " + value.getClass());
624+
throw new AthenaConnectorException("Unsupported value type: " + value.getClass(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
622625
}
623626
}
624627

@@ -632,7 +635,7 @@ public static AttributeValue jsonToAttributeValue(String jsonString, String key)
632635
{
633636
EnhancedDocument enhancedDocument = EnhancedDocument.fromJson(jsonString);
634637
if (!enhancedDocument.isPresent(key)) {
635-
throw new RuntimeException("Unknown attribute Key");
638+
throw new AthenaConnectorException("Unknown attribute Key", new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
636639
}
637640
return enhancedDocument.toMap().get(key);
638641
}
@@ -655,7 +658,7 @@ else if (firstElement instanceof Number) {
655658
} // Add other types if needed
656659

657660
// Fallback for unsupported set types
658-
throw new UnsupportedOperationException("Unsupported Set element type: " + firstElement.getClass());
661+
throw new AthenaConnectorException("Unsupported Set element type: " + firstElement.getClass(), new ErrorDetails().withErrorCode(FederationSourceErrorCode.InvalidInputException.toString()));
659662
}
660663

661664
private static AttributeValue handleListType(List<?> value)

0 commit comments

Comments
 (0)