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 c271c1ef6 fix(web): reject deleting a missing alert rule in mock mode
(#7122)
c271c1ef6 is described below
commit c271c1ef6892ffa4789fd213cc12792dd22067e2
Author: Qingyuan Wang <[email protected]>
AuthorDate: Wed Oct 28 00:41:00 2026 +0800
fix(web): reject deleting a missing alert rule in mock mode (#7122)
Mock mode's deleteAlertRule returned success for a rule that was not there,
so the
mock surface and the real API disagreed about the one case a caller has to
handle.
Throw "Alert rule not found" instead, matching the server.
The test conflicted with #7140, which added semantic-fingerprint
de-duplication to
the mock createAlertRule; both sets of cases are kept, and the new fixture
uses a
distinct metric so the de-duplication cannot swallow it.
---
web/src/services/opsService.test.ts | 21 +++++++++++++++++++++
web/src/services/opsService.ts | 3 ++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/web/src/services/opsService.test.ts
b/web/src/services/opsService.test.ts
index 650b8cde3..4eb78aeb4 100644
--- a/web/src/services/opsService.test.ts
+++ b/web/src/services/opsService.test.ts
@@ -237,6 +237,27 @@ describe('ops service mock data', () => {
}
});
+ it('rejects deleting a missing alert rule in mock mode', async () => {
+ const rule = await createAlertRule({
+ name: 'deleted-rule-marker',
+ metric: 'mock.delete.missing',
+ channels: ['email'],
+ });
+ await deleteAlertRule(rule.id, 'CLUSTER');
+
+ await expect(deleteAlertRule(rule.id, 'CLUSTER')).rejects.toThrow(
+ `Alert rule not found: ${rule.id}`,
+ );
+ await expect(deleteAlertRule(rule.id, 'BUSINESS')).rejects.toThrow(
+ `Alert rule not found: ${rule.id}`,
+ );
+ // The two rejections above delete by the id createAlertRule handed out,
which is Date.now()
+ // based. An id that was never issued keeps the case deterministic
regardless of that.
+ await expect(deleteAlertRule(999999, 'CLUSTER')).rejects.toThrow(
+ 'Alert rule not found: 999999',
+ );
+ });
+
it('imports and exports alert rules within the selected domain only', async
() => {
const imported = await importAlertRulesTransfer(
{
diff --git a/web/src/services/opsService.ts b/web/src/services/opsService.ts
index 1779a24f2..ed00ebe42 100644
--- a/web/src/services/opsService.ts
+++ b/web/src/services/opsService.ts
@@ -348,7 +348,8 @@ export async function deleteAlertRule(
): Promise<void> {
if (isMockMode()) {
const idx = alertRulesState[domain].findIndex((rule) => rule.id === id);
- if (idx >= 0) alertRulesState[domain].splice(idx, 1);
+ if (idx < 0) throw new Error(`Alert rule not found: ${id}`);
+ alertRulesState[domain].splice(idx, 1);
return;
}
return opsApi.deleteAlertRule(id, domain);