{"record":{"id":"7b9771748bc1fe84","repo":"apache/iceberg","slug":"interrupted-in-call-to-dropview","errorCode":null,"errorMessage":"Interrupted in call to dropView","messagePattern":"Interrupted in call to dropView","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java","lineNumber":331,"sourceCode":"          client -> {\n            client.dropTable(database, viewName, false, false);\n            return null;\n          });\n\n      if (lastViewMetadata != null) {\n        CatalogUtil.dropViewMetadata(ops.io(), lastViewMetadata);\n      }\n\n      LOG.info(\"Dropped view: {}\", identifier);\n      return true;\n    } catch (NoSuchObjectException e) {\n      LOG.info(\"Skipping drop, view does not exist: {}\", identifier, e);\n      return false;\n    } catch (TException e) {\n      throw new RuntimeException(\"Failed to drop view \" + identifier, e);\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new RuntimeException(\"Interrupted in call to dropView\", e);\n    }\n  }\n\n  @Override\n  public void renameTable(TableIdentifier from, TableIdentifier originalTo) {\n    renameTableOrView(from, originalTo, HiveOperationsBase.ContentType.TABLE);\n  }\n\n  @Override\n  public void renameView(TableIdentifier from, TableIdentifier to) {\n    renameTableOrView(from, to, HiveOperationsBase.ContentType.VIEW);\n  }\n\n  private List<TableIdentifier> listIcebergTables(\n      List<String> tableNames, Namespace namespace, String tableTypeProp)\n      throws TException, InterruptedException {\n    List<Table> tableObjects =\n        clients.run(client -> client.getTableObjectsByName(namespace.level(0), tableNames));","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java#L313-L349","documentation":"dropView() catches InterruptedException, restores the interrupt flag, and rethrows a RuntimeException with this message. The thread was interrupted while the metastore view-drop RPC was running, leaving the drop outcome indeterminate.","triggerScenarios":"Calling catalog.dropView(identifier) from a thread interrupted during the Thrift metastore call (task cancellation, pool shutdown, kill).","commonSituations":"Cancelling a Spark/Flink job cleaning up views; executor shutdown mid-cleanup; timeouts implemented via interrupt.","solutions":["Re-check view existence at the metastore to learn whether the drop landed.","Propagate the interrupt/cancellation instead of swallowing it.","Fix the source of interruption (shutdown ordering, timeouts) if unintended.","Retry only after the interruption source is gone."],"exampleFix":"// before\ntry { catalog.dropView(v); } catch (RuntimeException e) { LOG.warn(\"dropped?\", e); }\n// after\ntry {\n  catalog.dropView(v);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt();\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (Thread.currentThread().isInterrupted()) {\n  throw new InterruptedException(\"Interrupted before dropping view\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  catalog.dropView(viewId);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt();\n    throw e;\n  }\n  throw e;\n}","preventionTips":["Complete view cleanup before executor shutdown.","Treat interruption during drop as 'state unknown' and re-check existence.","Use cancellable futures rather than raw thread interrupts for timeouts."],"tags":["hive-metastore","interruption","threading","views"],"backgroundTag":"thread-interrupted","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}