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);