Skip to content

fix: monitor detail view fails when ZM Servers row has placeholder Hostname/Port=0 #120

@pliablepixels

Description

@pliablepixels

Report

User on the Tauri desktop client sees this in the Monitors list:

  • The monitor thumbnail shows a "camera with a line through it" (broken) icon with an MJPEG badge.
  • Hovering the tile shows a popup preview that streams correctly.
  • Clicking the tile opens the monitor detail view, where nothing plays and console shows requests like:
http://server.localdomain:0/zm/api/monitors/alarm/id:1/command:status.json?token=...

Note the hostname server.localdomain and port 0.

Root cause

Two different URL-construction paths:

  • Hover preview (components/monitors/MonitorHoverPreview.tsx:83-88) uses currentProfile.cgiUrl directly — the URL the user configured. Works.
  • Monitor detail view (pages/MonitorDetail.tsx:129) calls useServerUrls(monitor.Monitor.ServerId), which goes through lib/server-resolver.ts.

server-resolver.ts:67-96 builds a per-server URL map from /zm/api/servers/index.json. At line 76:

const port = server.Port ?? 443;

Nullish coalescing lets Port: 0 through unchanged. Combined with a placeholder Hostname: "server.localdomain" that many ZM single-server installs have by default in their Servers table, the resolver produces http://server.localdomain:0/zm/api and that base is passed to getAlarmStatus and every other API call for that monitor.

Expected behavior

The app should use the user's configured profile URL when the ZM Servers row looks like placeholder data (empty/missing Hostname, non-positive Port, or obvious placeholder hostnames like localhost, *.localdomain). The resolver already has a fallback path for missing rows — this issue is about treating obviously-broken rows as equivalent to missing.

Fix plan

In lib/server-resolver.ts::buildServerMap, skip rows that:

  • Have no Hostname (already skipped today)
  • Have Port <= 0 or non-numeric Port
  • Have a placeholder Hostname (localhost, *.localdomain)

Skipped rows won't land in the map, so resolveMonitorUrls naturally falls back to the profile defaults (same path as when ServerId is absent).

Test plan

  • Unit tests in lib/__tests__/server-resolver.test.ts:
    • buildServerMap skips rows with Port: 0
    • buildServerMap skips rows with Port: null
    • buildServerMap skips rows with placeholder hostnames (localhost, *.localdomain)
    • resolveMonitorUrls falls back to profile defaults when the ServerId points at a skipped row
  • Manual verification on the user's setup that the monitor detail view loads correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions