OtterMind/Chat2DB · critical · BusinessException

database.delete.connectionFailed

database.delete.connectionFailed

Error message

database.delete.connectionFailed

What it means

Thrown by requireConnection() when Chat2DBContext.getConnection() returns null after the connection context was expected to be established. This means the thread-bound JDBC connection is missing when the delete-prepare or delete-execute operation needs it. It typically indicates the connection was never opened, was already closed, or the context was not bound for this thread/request.

Source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDatabaseObjectDeleteServiceImpl.java:198

            throw new BusinessException("database.delete.notSupportDatabase");
        }
    }

    private void rejectSystemDatabase(String dbType, String databaseName) {
        if (DatabaseTypeEnum.MYSQL.name().equalsIgnoreCase(dbType)
                && MYSQL_SYSTEM_DATABASES.contains(StringUtils.lowerCase(databaseName))) {
            throw new BusinessException("database.delete.systemDatabaseForbidden");
        }
        if (DatabaseTypeEnum.POSTGRESQL.name().equalsIgnoreCase(dbType)
                && POSTGRESQL_SYSTEM_DATABASES.contains(StringUtils.lowerCase(databaseName))) {
            throw new BusinessException("database.delete.systemDatabaseForbidden");
        }
    }

    private Connection requireConnection() {
        Connection connection = Chat2DBContext.getConnection();
        if (connection == null) {
            throw new BusinessException("database.delete.connectionFailed");
        }
        return connection;
    }

    private void assertDatabaseExists(Connection connection, String dbType, String databaseName) {
        List<Database> databases = Chat2DBContext.getDbMetaData(dbType).databases(connection);
        boolean exists = databases != null && databases.stream()
                .anyMatch(database -> StringUtils.equals(database.getName(), databaseName));
        if (!exists) {
            throw new BusinessException("database.delete.databaseNotExists");
        }
    }

    private DatabaseObjectDeletePrepare prepareResult(String confirmName, String sqlPreview, String objectType,
                                                       String dbType) {
        return DatabaseObjectDeletePrepare.builder()
                .confirmName(confirmName)
                .sqlPreview(sqlPreview)

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Verify the datasource can connect: check DB server availability, credentials, and network reachability.
  2. Ensure the service is called within the request scope that binds a connection to Chat2DBContext (via connectionContextService).
  3. Check server logs for prior connection-acquisition failures or pool exhaustion.
Defensive patterns

Strategy: validation

Validate before calling

if (Chat2DBContext.getConnection() == null) {
    // surface a connection-setup error to the user; do not proceed
}

Try / catch

try {
    service.prepareDatabaseDelete(req);
} catch (BusinessException e) {
    if ("database.delete.connectionFailed".equals(e.getCode())) {
        // prompt user to reconnect / check datasource
    } else { throw e; }
}

Prevention

When it happens

Trigger: prepareDatabaseDelete or executeDatabaseDelete reaching requireConnection() (lines 68/112) when no connection is bound in Chat2DBContext. For PostgreSQL, reconnectForDatabaseDelete rebinds first; if that rebind fails to establish a connection, getConnection() returns null.

Common situations: The datasource connection pool is exhausted or the DB server is unreachable so the context never bound a connection; a code path that calls the service outside the normal request-scoped connection lifecycle; connection was closed by a prior operation or timeout.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/ac9d8d6b79c2b438. Report an issue: GitHub.