fix(dlna): always return non-nil device slice so API serializes [] not null

The DLNA device list endpoint could return {"devices":null} in two cases:
the SSDP-failure path returned a nil slice, and the cached path copied an
empty cache via append([]DLNADevice(nil), cache...) which also yields nil.
The web UI reads res.devices.length, so a null devices field crashed the
DLNA page to a white screen. Return non-nil slices in both paths and guard
the frontend with a null coalesce. Adds a regression test.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
soldosluka857
2026-05-30 04:34:12 +00:00
committed by Shuke
parent 7e83047fdb
commit b2ccd04844
3 changed files with 44 additions and 5 deletions
+5 -3
View File
@@ -114,7 +114,8 @@ func (d *DLNAService) ssdpDiscover(ctx context.Context, timeout time.Duration) (
func (d *DLNAService) Discover(ctx context.Context, force bool) ([]DLNADevice, error) {
d.mu.Lock()
if !force && time.Since(d.cachedAt) < 30*time.Second && d.cache != nil {
out := append([]DLNADevice(nil), d.cache...)
// Copy into a non-nil slice so an empty cache serializes as [] not null.
out := append(make([]DLNADevice, 0, len(d.cache)), d.cache...)
d.mu.Unlock()
return out, nil
}
@@ -123,9 +124,10 @@ func (d *DLNAService) Discover(ctx context.Context, force bool) ([]DLNADevice, e
locations, err := d.ssdpDiscover(ctx, 3*time.Second)
if err != nil {
// SSDP often fails on container networks; treat as "no devices"
// rather than 500 the API.
// rather than 500 the API. Return an empty (non-nil) slice so the
// JSON response is [] not null.
d.log.Debug("ssdp discover failed", zap.Error(err))
return nil, nil
return []DLNADevice{}, nil
}
devices := make([]DLNADevice, 0, len(locations))
for _, loc := range locations {