diff --git a/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java b/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java index f691fc06f5b7..61ad72db0d8e 100644 --- a/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java +++ b/paimon-core/src/main/java/org/apache/paimon/rest/RESTCatalog.java @@ -692,6 +692,10 @@ public void alterTable( } else if (StringUtils.equals( e.resourceType(), ErrorResponse.RESOURCE_TYPE_COLUMN)) { throw new ColumnNotExistException(identifier, e.resourceName()); + } else { + // rethrow other typed 404s, for example a DATABASE dropped + // concurrently; swallowing would report success for a failed ALTER + throw e; } } } catch (AlreadyExistsException e) { diff --git a/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTCatalogTest.java b/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTCatalogTest.java index 0054af3d1652..4725248f9ae6 100644 --- a/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTCatalogTest.java +++ b/paimon-core/src/test/java/org/apache/paimon/rest/MockRESTCatalogTest.java @@ -53,10 +53,12 @@ import org.apache.paimon.rest.auth.RESTAuthParameter; import org.apache.paimon.rest.exceptions.AlreadyExistsException; import org.apache.paimon.rest.exceptions.BadRequestException; +import org.apache.paimon.rest.exceptions.NoSuchResourceException; import org.apache.paimon.rest.exceptions.NotAuthorizedException; import org.apache.paimon.rest.exceptions.NotImplementedException; import org.apache.paimon.rest.requests.CreatePartitionsRequest; import org.apache.paimon.rest.responses.ConfigResponse; +import org.apache.paimon.rest.responses.ErrorResponse; import org.apache.paimon.schema.FileSystemSchemaManager; import org.apache.paimon.schema.Schema; import org.apache.paimon.schema.SchemaChange; @@ -79,6 +81,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mockito; import java.io.IOException; import java.net.URI; @@ -146,6 +149,37 @@ public void tearDown() throws Exception { } } + @Test + public void testAlterTableRethrowsForeignTypedNotFound() throws Exception { + // a 404 typed other than TABLE/COLUMN must not be swallowed into reported success + Identifier identifier = Identifier.create("test_alter_404", "t"); + RESTApi mockApi = Mockito.mock(RESTApi.class); + Mockito.doThrow( + new NoSuchResourceException( + ErrorResponse.RESOURCE_TYPE_DATABASE, + "test_alter_404", + "database missing")) + .when(mockApi) + .alterTable(Mockito.any(), Mockito.anyList()); + + java.lang.reflect.Field field = RESTCatalog.class.getDeclaredField("api"); + field.setAccessible(true); + Object original = field.get(restCatalog); + field.set(restCatalog, mockApi); + try { + assertThatThrownBy( + () -> + catalog.alterTable( + identifier, + Collections.singletonList( + SchemaChange.setOption("k", "v")), + false)) + .isInstanceOf(org.apache.paimon.rest.exceptions.NoSuchResourceException.class); + } finally { + field.set(restCatalog, original); + } + } + @Test void testCompatibilityWithServerWithoutSchemaEndpoints() throws Exception { restCatalogServer.setSchemaEndpointsSupported(false);