Skip to content

Conversation

@LYD031106
Copy link

Purpose of the PR

Main Changes

The PR fixes the issue where the graph clear API mistakenly clears the meta table in Hbase backend storage.

Verifying these changes

  • Trivial rework / code cleanup without any test coverage. (No Need)
  • Already covered by existing tests, such as (please modify tests here).
  • Need tests and can be verified as follows:
    • xxx

Does this PR potentially affect the following parts?

Documentation Status

  • Doc - TODO
  • Doc - Done
  • Doc - No Need

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working store Store module labels Nov 16, 2025
}
}

@Test
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Test coverage insufficient

The test only verifies version equality but doesn't validate:

  1. Meta table content: Check that specific meta entries (like backend version, graph name, etc.) are preserved
  2. Data table clearing: Verify that actual graph data (vertices, edges) are properly cleared
  3. Concurrent operations: Test behavior when truncate is called during other operations

Suggestion:

@Test
public void testHbaseMetaVersion(){
    // Insert some test data
    // ... add vertices/edges ...
    
    String beforeVersion = this.store.storedVersion();
    // Get other meta entries
    
    this.store.truncate();
    
    String afterVersion = this.store.storedVersion();
    Assert.assertEquals(beforeVersion, afterVersion);
    
    // Verify data is cleared but meta is intact
    // ... check vertices/edges are gone ...
    // ... check other meta entries preserved ...
}


private static final String GRAPH_NAME = "test_graph";

@Before
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Test setup/teardown issue

Both BaseHbaseUnitTest and HbaseUnitTest have setup/teardown methods that may cause issues:

  1. Duplicate cleanup: @After in both base and child class will close store/provider twice
  2. Setup order: Child's @Before runs after parent's, but calls provider.open() which may conflict

Suggestion:

Suggested change
@Before
@Before
public void setUp(){
super.setup(); // Call parent setup first
this.provider.open(GRAPH_NAME);
this.provider.init();
}
@After
public void teardown(){
// Remove duplicate cleanup - handled by parent
// Only add child-specific cleanup here if needed
}

}

@After
public void down(){
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Code quality: Silent exception swallowing

Using empty catch blocks makes debugging difficult. Consider:

Suggested change
public void down(){
@After
public void down(){
if (this.store != null) {
try {
this.store.close();
} catch (Exception e) {
LOG.warn("Failed to close store", e);
}
}
if (this.provider != null) {
try {
this.provider.close();
} catch (Exception e) {
LOG.warn("Failed to close provider", e);
}
}
}

import org.apache.hugegraph.unit.FakeObjects;
import org.junit.After;
import org.junit.Before;

Copy link
Member

Choose a reason for hiding this comment

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

🧹 Naming: Space missing in class declaration

Minor style issue:

Suggested change
public class BaseHbaseUnitTest extends BaseUnitTest {

"Failed to truncate table for '%s' store", e, this.store);
}

this.init();
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Root cause analysis: Design issue in truncate implementation

After reviewing the code, I found the real problem:

Current Issue:

  • HbaseSystemStore.tableNames() (line 572-576) includes the meta table in the list
  • truncate() clears ALL tables returned by tableNames(), including the meta table
  • Adding init() is a workaround, but meta table should never be cleared in the first place

Proper Fix:
Override truncate() in HbaseSystemStore to exclude meta table:

@Override
public void truncate() {
    // Save meta table before truncate
    List<String> originalTables = this.tableNames();
    
    // Temporarily remove meta table from truncation
    // Then call super.truncate() on data tables only
    // Or better: add a separate method tableNamesToTruncate()
}

Alternative approach (cleaner):

protected List<String> tableNamesToTruncate() {
    // Only return data tables, not meta/system tables
    return super.tableNames(); // Don't include meta.table()
}

Then use tableNamesToTruncate() in the truncate() method instead of tableNames().

This matches how MySQL backend works - it only truncates data tables, never system tables.

Copy link
Author

Choose a reason for hiding this comment

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

Your solution is indeed a superior approach. By overriding the truncate() method to exclude metadata tables, we are solving the problem at the design level, which is far more elegant and robust than relying on a temporary solution involving initialization calls.

I will proceed with the modifications as suggested, implementing this fix for the HBase backend. For consistency, I will also apply the same change to the MySQL backend in the corresponding PR (#2888).

Regarding the current implementation for the RocksDB backend, which uses the direct init() call workaround, I believe it should also be optimized. Adopting this unified strategy of overriding the truncate() method will enhance code consistency and maintainability across all backends.Here is the implementation of the truncate() method in RocksStore.

    @Override
    public synchronized void truncate() {
        Lock writeLock = this.storeLock.writeLock();
        writeLock.lock();
        try {
            this.checkOpened();

            this.clear(false);
            this.init();
            // Clear write-batch
            this.dbs.values().forEach(BackendSessionPool::forceResetSessions);
            LOG.debug("Store truncated: {}", this.store);
        } finally {
            writeLock.unlock();
        }
    }

Thank you again for your valuable feedback. It has truly helped me arrive at a much more elegant solution!

return this.tables.values().stream()
.filter(table -> !(table instanceof HbaseTables.Meta ||
table instanceof HbaseTables.Counters))
.map(BackendTable::table)
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Critical: Logic Error - Counters Table Should Be Truncated

The Counters table contains graph-specific data like vertex/edge ID sequences. When truncating a graph, this data should be cleared to avoid ID conflicts when repopulating the graph.

Only the Meta table (which stores backend version metadata) should be preserved during truncation.

Suggested change
.map(BackendTable::table)
protected List<String> truncatedTableNames() {
return this.tables.values().stream()
.filter(table -> !(table instanceof HbaseTables.Meta))
.map(BackendTable::table)
.collect(Collectors.toList());
}

}

@Test
public void testMysqlMetaVersion(){
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Test Method Name Mismatch

The test method is named testMysqlMetaVersion() but it's testing HBase functionality. This appears to be a copy-paste error from MySQL tests.

Suggested change
public void testMysqlMetaVersion(){
@Test
public void testHbaseMetaVersionAfterTruncate() {

This makes the test's purpose clearer and matches the actual functionality being tested.

super.setup();
}

@Test
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Incomplete Test Coverage

The test only verifies that meta version is preserved, but doesn't verify the actual truncation behavior. Consider adding assertions to verify:

  1. Data tables are actually truncated (e.g., insert some data, truncate, verify data is gone)
  2. Meta table content remains intact
  3. The graph can be used normally after truncation

Example enhancement:

@Test
public void testHbaseMetaVersionAfterTruncate() {
    BackendStore systemStore = this.provider.loadSystemStore(config);
    BackendStore graphStore = this.provider.loadGraphStore(config);
    
    // Record initial version
    String beforeVersion = systemStore.storedVersion();
    
    // Insert some test data to verify truncation
    // ... add test data insertion code ...
    
    // Perform truncation
    this.provider.truncate();
    
    // Verify version preserved
    String afterVersion = systemStore.storedVersion();
    Assert.assertEquals(beforeVersion, afterVersion);
    
    // Verify data tables are empty
    // ... add verification code ...
}

import org.apache.hugegraph.unit.BaseUnitTest;
import org.junit.After;

public class BaseHbaseUnitTest extends BaseUnitTest{
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Code Style: Formatting

Missing space after class declaration:

Suggested change
public class BaseHbaseUnitTest extends BaseUnitTest{
public class BaseHbaseUnitTest extends BaseUnitTest {

this.enableTables();
throw new BackendException(
"Failed to truncate table for '%s' store", e, this.store);
}
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Minor: Unnecessary Whitespace Change

Removing this blank line is cosmetic and adds noise to the diff without functional benefit. Consider keeping the original formatting to make the diff cleaner and focus on actual logic changes.

Comment on lines 3 to 16
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
Copy link
Member

Choose a reason for hiding this comment

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

wrong header format


protected List<String> truncatedTableNames() {
return this.tables.entrySet().stream()
.filter(e -> !(HugeType.META == e.getKey()))
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Critical: Potential NullPointerException

The filter condition HugeType.META == e.getKey() may not correctly handle null keys, though this is unlikely in practice. However, the main concern is whether HugeType.META is actually the correct type to filter out.

Consider adding a comment explaining why META type should be preserved during truncation to improve code maintainability.

Suggested change
.filter(e -> !(HugeType.META == e.getKey()))
protected List<String> truncatedTableNames() {
// Exclude META table to preserve system metadata (e.g., version info) during graph clear
return this.tables.entrySet().stream()
.filter(e -> !(HugeType.META == e.getKey()))
.map(e -> e.getValue().table())
.collect(Collectors.toList());
}


protected HugeConfig config;
protected HbaseStoreProvider provider;
protected HbaseSessions sessions;
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing @Before annotation

The method is named setup() but the annotation @Before is missing. JUnit won't automatically call this method before each test. This could cause tests to fail or behave unexpectedly.

Suggested change
protected HbaseSessions sessions;
@Before
public void setup() throws IOException {

this.provider.loadGraphStore(config).open(config);
this.provider.loadSchemaStore(config).open(config);
this.provider.init();
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Naming inconsistency: down() should be tearDown()

The cleanup method should follow JUnit naming conventions and be named tearDown() to match the common pattern.

Suggested change
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
@After
public void tearDown() {

this.config = new HugeConfig(conf);
this.provider = new HbaseStoreProvider();
this.provider.open(GRAPH_NAME);
this.provider.loadSystemStore(config).open(config);
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing space after comma - code style

For code consistency, add a space after commas in method calls.

Suggested change
this.provider.loadSystemStore(config).open(config);
this.sessions = new HbaseSessions(config, GRAPH_NAME, this.provider.loadGraphStore(config).store());

}

@After
public void down(){
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing space after comma in log statement

Suggested change
public void down(){
LOG.warn("Failed to close provider", e);

import org.junit.After;

import java.io.IOException;

Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing space after class declaration

Suggested change
public class BaseHbaseUnitTest extends BaseUnitTest {

this.provider.loadGraphStore(config).open(config);
this.provider.loadSchemaStore(config).open(config);
this.provider.init();
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing space after method opening brace

Suggested change
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
public void tearDown() {

this.provider.loadGraphStore(config).open(config);
this.provider.loadSchemaStore(config).open(config);
this.provider.init();
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Critical: Resource leak - HbaseSessions not closed

The sessions field is opened in setup() but never closed in the cleanup method. This could lead to HBase connection leaks.

Suggested change
this.sessions = new HbaseSessions(config,GRAPH_NAME, this.provider.loadGraphStore(config).store());
@After
public void tearDown() {
if (this.sessions != null) {
try {
this.sessions.close();
} catch (Exception e) {
LOG.warn("Failed to close sessions", e);
}
}
if (this.provider != null) {


// Insert test data
testsession.put("g_v", "f".getBytes(), "row_trunc_v".getBytes(), StringEncoding.encode("q"), StringEncoding.encode("v"));
testsession.put("g_oe", "f".getBytes(), "row_trunc_oe".getBytes(), StringEncoding.encode("q"), StringEncoding.encode("v"));
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Potential resource leak with iterators

If an assertion fails, the subsequent close() calls won't execute. Consider using try-with-resources or try-finally blocks.

Suggested change
testsession.put("g_oe", "f".getBytes(), "row_trunc_oe".getBytes(), StringEncoding.encode("q"), StringEncoding.encode("v"));
// Verify data insertion success
try (BackendIterator<Result> vIterator = testsession.get("g_v", "f".getBytes(), "row_trunc_v".getBytes());
BackendIterator<Result> oeIterator = testsession.get("g_oe", "f".getBytes(), "row_trunc_oe".getBytes());
BackendIterator<Result> ieIterator = testsession.get("g_ie", "f".getBytes(), "row_trunc_ie".getBytes())) {
Assert.assertTrue("data should exist", vIterator.hasNext());
Assert.assertTrue("data should exist", oeIterator.hasNext());
Assert.assertTrue("data should exist", ieIterator.hasNext());
}

this.provider.truncate();

// Verify system version remains unchanged after truncation
String afterVersion = systemStore.storedVersion();
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Missing space after comma in Assert.assertNotNull

Suggested change
String afterVersion = systemStore.storedVersion();
Assert.assertNotNull("System metadata version should exist", afterVersion);

.collect(Collectors.toList());
}

protected List<String> truncatedTableNames() {
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Critical: Method name doesn't follow Java naming conventions

The method name truncatedTableNames() is grammatically incorrect and misleading. It suggests tables that have already been truncated, when it actually returns tables that SHOULD be truncated.

Suggested change
protected List<String> truncatedTableNames() {
protected List<String> getNonMetaTableNames() {
// Exclude meta table to preserve system metadata during graph clear
return this.tables.entrySet().stream()
.filter(e -> !(HugeType.META == e.getKey()))
.map(e -> e.getValue().table())
.collect(Collectors.toList());
}

Alternative names: getClearableTableNames(), getDataTableNames(), or getTableNamesExcludingMeta()


protected List<String> truncatedTableNames() {
// Exclude meta table to preserve system metadata during graph clear
return this.tables.entrySet().stream()
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Consider defensive programming: check for null HugeType

While unlikely, if e.getKey() is null, this comparison would fail with NPE. Consider using Objects.equals() or put the enum constant on the left side.

Suggested change
return this.tables.entrySet().stream()
.filter(e -> !HugeType.META.equals(e.getKey()))

Copy link
Author

Choose a reason for hiding this comment

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

The current code 'HugeType.META == e.getKey()' is already NPE-safe regardless of which operand is null, as the '==' operator never throws NullPointerException.

public void setup() throws IOException {
Configuration conf = Utils.getConf();
this.config = new HugeConfig(conf);
this.provider = new HbaseStoreProvider();
Copy link
Member

Choose a reason for hiding this comment

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

‼️ Critical: Potential resource leak in setup()

If any exception occurs after opening stores but before sessions.open(), the opened stores won't be properly closed. This can lead to resource leaks in test execution.

Suggested change
this.provider = new HbaseStoreProvider();
@Before
public void setup() throws IOException {
Configuration conf = Utils.getConf();
this.config = new HugeConfig(conf);
this.provider = new HbaseStoreProvider();
try {
this.provider.open(GRAPH_NAME);
this.provider.loadSystemStore(config).open(config);
this.provider.loadGraphStore(config).open(config);
this.provider.loadSchemaStore(config).open(config);
this.provider.init();
this.sessions = new HbaseSessions(config, GRAPH_NAME,
this.provider.loadGraphStore(config).store());
this.sessions.open();
} catch (Exception e) {
tearDown();
throw e;
}
}

LOG.warn("Failed to close sessions ", e);
}
}
if (this.provider != null){
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Code style: inconsistent spacing

Missing space after if keyword. Per project code style guidelines, control flow statements should have space before parentheses.

Suggested change
if (this.provider != null){
if (this.provider != null) {

}
if (this.provider != null){
try {
this.provider.close();
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Code style: inconsistent spacing

Missing space after catch keyword.

Suggested change
this.provider.close();
} catch (Exception e) {

try {
this.provider.close();
}catch (Exception e){
LOG.warn("Failed to close provider ",e);
Copy link
Member

Choose a reason for hiding this comment

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

🧹 Code style: inconsistent spacing

Missing space after closing brace and before catch. Should be } catch, not }catch.

Suggested change
LOG.warn("Failed to close provider ",e);
LOG.warn("Failed to close provider ", e);


// Verify data insertion success
try (
BackendIterator<Result> vIterator = testsession.get("g_v", "f".getBytes(StandardCharsets.UTF_8), "row_trunc_v".getBytes(StandardCharsets.UTF_8));
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Consider using try-with-resources for session management

The session testsession is not explicitly closed, which could lead to resource leaks. While it might be managed by the parent sessions object, it's better to be explicit.

Consider wrapping the session usage in a try-with-resources block or explicitly closing it after use.

// Record system version before truncation
String beforeVersion = systemStore.storedVersion();

HbaseSessions.Session testsession = this.sessions.session();
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ Test isolation concern: verify test data cleanup

The test inserts data with specific row keys (row_trunc_v, row_trunc_oe, row_trunc_ie). If this test runs multiple times or fails mid-execution, residual data might affect subsequent runs.

Consider:

  1. Using unique row keys per test run (e.g., append timestamp/UUID)
  2. Adding explicit cleanup in @Before setup
  3. Verifying the @After teardown properly cleans all test data

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug where the HBase graph clear API (truncate()) was incorrectly clearing the system metadata table. The fix introduces a new truncatedTableNames() method that returns only the tables that should be cleared during truncation, while preserving system metadata like backend version information stored in the meta table.

Key Changes

  • Added truncatedTableNames() method in HbaseStore to filter tables for truncation
  • Modified truncate() to use truncatedTableNames() instead of tableNames()
  • Added comprehensive unit tests to verify meta table preservation after truncation

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
hugegraph-server/hugegraph-hbase/src/main/java/org/apache/hugegraph/backend/store/hbase/HbaseStore.java Introduces truncatedTableNames() method to exclude meta table and updates truncate() to use it instead of tableNames()
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/hbase/BaseHbaseUnitTest.java New base test class for HBase unit tests with setup/teardown infrastructure
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/hbase/HbaseUnitTest.java New test case verifying meta table version persists after truncation while graph data is cleared

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +119 to +121
return this.tables.entrySet().stream()
.filter(e -> !(HugeType.META == e.getKey()))
.map(e -> e.getValue().table())
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

This filter condition !(HugeType.META == e.getKey()) is redundant because HugeType.META is never registered via registerTableManager() and therefore will never exist in the this.tables map. The meta table is added separately in HbaseSystemStore.tableNames() (line 582) by calling this.meta.table().

The fix works correctly because truncatedTableNames() simply doesn't include the meta table at all (since it's not in the map), but the explicit filter is misleading and suggests META might be in the map. Consider removing the filter:

protected List<String> truncatedTableNames() {
    // Exclude meta table to preserve system metadata during graph clear
    return this.tables.values().stream()
                      .map(BackendTable::table)
                      .collect(Collectors.toList());
}
Suggested change
return this.tables.entrySet().stream()
.filter(e -> !(HugeType.META == e.getKey()))
.map(e -> e.getValue().table())
return this.tables.values().stream()
.map(BackendTable::table)

Copilot uses AI. Check for mistakes.
LOG.warn("Failed to close sessions ", e);
}
}
if (this.provider != null){
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Missing space after if keyword. Should be if (this.provider != null) { for consistency with the code style used elsewhere in the method (line 56).

Suggested change
if (this.provider != null){
if (this.provider != null) {

Copilot uses AI. Check for mistakes.
if (this.provider != null){
try {
this.provider.close();
}catch (Exception e){
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Missing space after catch keyword. Should be } catch (Exception e) { for consistency with the code style used on line 59.

Suggested change
}catch (Exception e){
} catch (Exception e) {

Copilot uses AI. Check for mistakes.
if (this.provider != null){
try {
this.provider.close();
}catch (Exception e){
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Missing space after catch keyword. Should be } catch (Exception e) { for consistency with the code style used on line 59.

Suggested change
}catch (Exception e){
} catch (Exception e) {

Copilot uses AI. Check for mistakes.
try {
this.provider.close();
}catch (Exception e){
LOG.warn("Failed to close provider ",e);
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Missing space after comma in log message. Should be "Failed to close provider ", e for consistency with line 60.

Suggested change
LOG.warn("Failed to close provider ",e);
LOG.warn("Failed to close provider ", e);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files. store Store module

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

[Bug] The backend store version is inconsistent

2 participants