This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 29d1b69a fix(dashboard): fail loudly when collection returns no 
topology (#1655)
29d1b69a is described below

commit 29d1b69a2934cfefd5b8d2b7676622a081788d2e
Author: aias00 <[email protected]>
AuthorDate: Tue Aug 11 20:45:15 2026 +0800

    fix(dashboard): fail loudly when collection returns no topology (#1655)
---
 .../provider/apache/RocketMQDashboardProvider.java |  9 ++++---
 .../apache/RocketMQDashboardProviderTest.java      | 28 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProvider.java
 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProvider.java
index 15488981..5db3dd08 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProvider.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProvider.java
@@ -33,6 +33,7 @@ import 
org.apache.rocketmq.remoting.protocol.route.TopicRouteData;
 import 
org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig;
 import org.apache.rocketmq.studio.cluster.broker.MqAdminExtFactory;
 import org.apache.rocketmq.studio.cluster.broker.RuntimeAdminClientResolver;
+import org.apache.rocketmq.studio.common.exception.BusinessException;
 import org.apache.rocketmq.studio.common.domain.enums.ClusterStatus;
 import org.apache.rocketmq.studio.common.domain.enums.ClusterType;
 import org.apache.rocketmq.studio.common.domain.enums.InstanceType;
@@ -98,8 +99,7 @@ public class RocketMQDashboardProvider implements 
DashboardProvider {
         try {
             ClusterInfo clusterInfo = admin.examineBrokerClusterInfo();
             if (clusterInfo == null) {
-                log.warn("NameServer returned no cluster topology, returning 
empty dashboard");
-                return emptyDashboard();
+                throw new BusinessException(502, "Failed to collect dashboard 
data: NameServer returned no cluster topology");
             }
             // The NameServer topology is decoded from JSON; a payload missing 
either
             // table yields null here. Treat it as empty so a partial topology 
degrades
@@ -283,8 +283,11 @@ public class RocketMQDashboardProvider implements 
DashboardProvider {
             }
 
         } catch (Exception e) {
+            if (e instanceof BusinessException businessException) {
+                throw businessException;
+            }
             log.error("Failed to collect dashboard data from RocketMQ 
cluster", e);
-            return emptyDashboard();
+            throw new BusinessException(502, "Failed to collect dashboard 
data: " + e.getMessage());
         }
 
         long messagesPerSecond = tpsIn + tpsOut;
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProviderTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProviderTest.java
index c2bb4b54..1849931f 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProviderTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQDashboardProviderTest.java
@@ -27,6 +27,7 @@ import org.apache.rocketmq.remoting.protocol.body.TopicList;
 import org.apache.rocketmq.remoting.protocol.route.BrokerData;
 import org.apache.rocketmq.studio.cluster.broker.MqAdminExtFactory;
 import org.apache.rocketmq.studio.cluster.broker.RuntimeAdminClientResolver;
+import org.apache.rocketmq.studio.common.exception.BusinessException;
 import org.apache.rocketmq.studio.common.domain.enums.ClusterStatus;
 import org.apache.rocketmq.studio.common.domain.enums.ClusterType;
 import org.apache.rocketmq.studio.common.domain.enums.InstanceType;
@@ -36,6 +37,7 @@ import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -82,6 +84,32 @@ class RocketMQDashboardProviderTest {
         assertThat(dashboard.getClusters()).isEmpty();
     }
 
+    @Test
+    void 
dashboardShouldRejectAnUnavailableTopologyInsteadOfReturningAnEmptyOverview() 
throws Exception {
+        DefaultMQAdminExt adminExt = mock(DefaultMQAdminExt.class);
+        when(adminExt.examineBrokerClusterInfo()).thenReturn(null);
+
+        RocketMQDashboardProvider provider = newProvider(adminExt);
+
+        assertThatThrownBy(provider::getDashboardData)
+                .isInstanceOf(BusinessException.class)
+                .satisfies(error -> assertThat(((BusinessException) 
error).getCode()).isEqualTo(502))
+                .hasMessageContaining("Failed to collect dashboard data");
+    }
+
+    @Test
+    void dashboardShouldRejectAdminFailuresInsteadOfReturningAnEmptyOverview() 
throws Exception {
+        DefaultMQAdminExt adminExt = mock(DefaultMQAdminExt.class);
+        when(adminExt.examineBrokerClusterInfo()).thenThrow(new 
IllegalStateException("access denied"));
+
+        RocketMQDashboardProvider provider = newProvider(adminExt);
+
+        assertThatThrownBy(provider::getDashboardData)
+                .isInstanceOf(BusinessException.class)
+                .satisfies(error -> assertThat(((BusinessException) 
error).getCode()).isEqualTo(502))
+                .hasMessageContaining("access denied");
+    }
+
     @Test
     void dashboardShouldSkipBrokerWithoutAddressTable() throws Exception {
         DefaultMQAdminExt adminExt = mock(DefaultMQAdminExt.class);

Reply via email to