fix(status): dashboard keeps a watchdog-exited gateway degraded with its reason
`/api/status` mapped a not-running gateway's retained record through `retained_gateway_state`, which only kept `startup_failed`; a watchdog-stamped `degraded` + `exit_reason` of a dead PID became a bare `stopped` with the reason nulled, so the sidebar strip and System page read "Stopped" while `hermes gateway status` said "exited degraded: event loop stopped dispatching". Retain `degraded` under the same rule as `startup_failed` (only while `desired_state` still wants the gateway running, and only for the watchdog reasons in the new `gateway.status.WATCHDOG_EXIT_REASONS`); the resolver already keeps `gateway_exit_reason` for any non-`stopped` verdict. The sidebar strip gains the `degraded` label (warning while live, destructive when the process is gone) and the System page describes a dead `degraded` record as a watchdog exit. `/api/messaging/platforms` keeps yielding `gateway_stopped` for it — the channels really are down. Invariant tests: retained_gateway_state keeps/drops the verdict by desired_state and exit_reason; /api/status carries degraded + exit_reason for the dead PID and stopped/null after `hermes gateway stop`.
This commit is contained in:
@@ -57,6 +57,12 @@ export function gatewayLine(
|
||||
running: { label: g.running, tone: "text-success" },
|
||||
starting: { label: g.starting, tone: "text-warning" },
|
||||
startup_failed: { label: g.failed, tone: "text-destructive" },
|
||||
// Live: some channels offline. Retained on a dead PID: a watchdog hard-exited a wedged
|
||||
// process (gateway_exit_reason names it) — same verdict `hermes gateway status` prints.
|
||||
degraded: {
|
||||
label: g.degraded,
|
||||
tone: status.gateway_running ? "text-warning" : "text-destructive",
|
||||
},
|
||||
stopped: { label: g.stopped, tone: "text-muted-foreground" },
|
||||
};
|
||||
if (status.gateway_state && byState[status.gateway_state]) {
|
||||
|
||||
@@ -65,6 +65,7 @@ export const en: Translations = {
|
||||
activeSessionsLabel: "Active Sessions:",
|
||||
gatewayStatusLabel: "Gateway Status:",
|
||||
gatewayStrip: {
|
||||
degraded: "Degraded",
|
||||
failed: "Start failed",
|
||||
off: "Off",
|
||||
running: "Running",
|
||||
|
||||
@@ -84,6 +84,7 @@ export interface Translations {
|
||||
activeSessionsLabel: string;
|
||||
gatewayStatusLabel: string;
|
||||
gatewayStrip: {
|
||||
degraded: string;
|
||||
failed: string;
|
||||
off: string;
|
||||
running: string;
|
||||
|
||||
@@ -33,11 +33,15 @@ const GATEWAY_STATE_COPY: Record<string, string> = {
|
||||
startup_failed: "Failed to start — see Logs",
|
||||
};
|
||||
|
||||
/** A `degraded` record of a dead process is a watchdog exit, not a live gateway with channels down. */
|
||||
const GATEWAY_EXITED_DEGRADED_COPY = "Exited: a watchdog stopped a wedged gateway — see Logs";
|
||||
|
||||
/** Plain description of the gateway's state; null/unknown falls back to running/stopped. */
|
||||
export function gatewayStateDescription(
|
||||
state: string | null | undefined,
|
||||
running: boolean | undefined,
|
||||
): string {
|
||||
if (state === "degraded" && running === false) return GATEWAY_EXITED_DEGRADED_COPY;
|
||||
if (state && GATEWAY_STATE_COPY[state]) return GATEWAY_STATE_COPY[state];
|
||||
return running ? GATEWAY_STATE_COPY.running : GATEWAY_STATE_COPY.stopped;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user