Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly categorize external errors in Iceberg REST catalog #24828

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mayankvadariya
Copy link
Contributor

@mayankvadariya mayankvadariya commented Jan 28, 2025

Description

Failing stack trace

"org.apache.iceberg.rest.ErrorHandlers$OAuthErrorHandler.accept(ErrorHandlers.java:247)",
"org.apache.iceberg.rest.ErrorHandlers$OAuthErrorHandler.accept(ErrorHandlers.java:228)",
"org.apache.iceberg.rest.HTTPClient.throwFailure(HTTPClient.java:211)",
"org.apache.iceberg.rest.HTTPClient.execute(HTTPClient.java:323)",
"org.apache.iceberg.rest.HTTPClient.execute(HTTPClient.java:262)",
"org.apache.iceberg.rest.HTTPClient.postForm(HTTPClient.java:409)",
"org.apache.iceberg.rest.auth.OAuth2Util.fetchToken(OAuth2Util.java:264)",
"org.apache.iceberg.rest.auth.OAuth2Util$AuthSession.fromCredential(OAuth2Util.java:693)",
"org.apache.iceberg.rest.RESTSessionCatalog.lambda$newSession$6(RESTSessionCatalog.java:1076)",
"org.apache.iceberg.rest.RESTSessionCatalog.lambda$session$1(RESTSessionCatalog.java:342)",
"com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent$14(BoundedLocalCache.java:2688)",
"java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1921)",
"com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2686)",
"com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2669)",
"com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:112)",
"com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:62)",
"org.apache.iceberg.rest.RESTSessionCatalog.session(RESTSessionCatalog.java:336)",
"org.apache.iceberg.rest.RESTSessionCatalog.headers(RESTSessionCatalog.java:352)",
"org.apache.iceberg.rest.RESTSessionCatalog.listNamespaces(RESTSessionCatalog.java:634)",
"org.apache.iceberg.catalog.SessionCatalog.listNamespaces(SessionCatalog.java:276)",
"io.trino.plugin.iceberg.catalog.rest.TrinoRestCatalog.listNamespaces(TrinoRestCatalog.java:190)",
"io.trino.plugin.iceberg.IcebergMetadata.listSchemaNames(IcebergMetadata.java:486)",

Additional context and related issues

Release notes

(x) This is not user-visible or is docs only, and no release notes are required.

@cla-bot cla-bot bot added the cla-signed label Jan 28, 2025
@github-actions github-actions bot added the iceberg Iceberg connector label Jan 28, 2025
@mayankvadariya mayankvadariya force-pushed the mayank/rest-catalog-exception branch from a4df018 to 0444c4e Compare January 28, 2025 23:01
@ebyhr ebyhr requested review from ebyhr and pajaks January 28, 2025 23:42
@mayankvadariya mayankvadariya force-pushed the mayank/rest-catalog-exception branch from 0444c4e to 14b5be2 Compare January 28, 2025 23:54
@@ -233,6 +234,10 @@ public void testDropTableWithMissingMetadataFile()
public void testDropTableWithMissingSnapshotFile()
{
assertThatThrownBy(super::testDropTableWithMissingSnapshotFile)
.isInstanceOf(QueryFailedException.class)
.cause()
Copy link
Member

Choose a reason for hiding this comment

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

Can we check that cause is TrinoException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had tried it but it fails with some error.

.cause()
.isInstanceOf(TrinoException.class)

java.lang.AssertionError: 
Expecting actual throwable to be an instance of:
  io.trino.spi.TrinoException
but was:
  io.trino.spi.TrinoException: Failed to drop table: test_drop_table_with_missing_snapshot_file_0noolj73ah
	at io.trino.plugin.iceberg.catalog.rest.TrinoRestCatalog.dropTable(TrinoRestCatalog.java:464)
	at io.trino.plugin.iceberg.IcebergMetadata.dropTable(IcebergMetadata.java:2284)
	at io.trino.plugin.base.classloader.ClassLoaderSafeConnectorMetadata.dropTable(ClassLoaderSafeConnectorMetadata.java:451)
	...(16 remaining lines not displayed - this can be changed with Assertions.setMaxStackTraceElementsDisplayed)

return restSessionCatalog.listNamespaces(convert(session)).stream()
.map(this::toSchemaName)
.collect(toImmutableList());
try {
Copy link
Member

Choose a reason for hiding this comment

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

If try would include also collectNamespaces exception handling inside would not be necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I kept it separately in case collectNamespaces is to be called from some other method.

@@ -251,10 +274,24 @@ public List<TableInfo> listTables(ConnectorSession session, Optional<String> nam

ImmutableList.Builder<TableInfo> tables = ImmutableList.builder();
for (Namespace restNamespace : namespaces) {
listTableIdentifiers(restNamespace, () -> restSessionCatalog.listTables(sessionContext, toRemoteNamespace(session, restNamespace))).stream()
listTableIdentifiers(restNamespace, () -> {
Copy link
Member

Choose a reason for hiding this comment

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

Can we have one catch for whole method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I kept it separately to throw different error messages.

@mayankvadariya mayankvadariya force-pushed the mayank/rest-catalog-exception branch 2 times, most recently from a673083 to 593f5c6 Compare January 29, 2025 20:28
@@ -191,7 +206,7 @@ public void dropNamespace(ConnectorSession session, String namespace)
throw new SchemaNotFoundException(namespace);
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, format("Failed to drop namespace: %s", namespace), e);
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to drop namespace: '%s'".formatted(namespace), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove :

@@ -208,6 +223,9 @@ public Map<String, Object> loadNamespaceMetadata(ConnectorSession session, Strin
catch (NoSuchNamespaceException e) {
throw new SchemaNotFoundException(namespace);
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to load namespace metadata for: '%s'".formatted(namespace), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Failed to load metadata for namespace '%s'

}));
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to create namespace: '%s'".formatted(namespace), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

restSessionCatalog.registerTable(convert(session), tableIdentifier, tableMetadata.metadataFileLocation());
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to register table: '%s'".formatted(tableName.getTableName()), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

}
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to unregister table: '%s'".formatted(tableName.getTableName()), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

throw new TrinoException(ICEBERG_CATALOG_ERROR, format("Failed to drop table: %s", schemaTableName));
try {
if (!restSessionCatalog.purgeTable(convert(session), toRemoteTable(session, schemaTableName, true))) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to drop table: '%s'".formatted(schemaTableName));
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to drop table: '%s'".formatted(schemaTableName));
}
}
catch (RESTException e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

baseTable = (BaseTable) restSessionCatalog.loadTable(convert(session), toRemoteObject(session, schemaTableName));
}
catch (RESTException e) {
throw new TrinoException(ICEBERG_CATALOG_ERROR, "Failed to load table: '%s'".formatted(schemaTableName.getTableName()), e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop :

@wendigo
Copy link
Contributor

wendigo commented Jan 30, 2025

Drop these : as these are redundant.

"Failed to drop table 'test'" looks better than "Failed to drop table: 'test'"

@mayankvadariya mayankvadariya force-pushed the mayank/rest-catalog-exception branch from 593f5c6 to e79875b Compare January 31, 2025 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed iceberg Iceberg connector
Development

Successfully merging this pull request may close these issues.

3 participants