diff --git a/apps/web/src/app/server-storage/server-instance-probe.spec.ts b/apps/web/src/app/server-storage/server-instance-probe.spec.ts index 9add42ae5..65eed0607 100644 --- a/apps/web/src/app/server-storage/server-instance-probe.spec.ts +++ b/apps/web/src/app/server-storage/server-instance-probe.spec.ts @@ -78,6 +78,14 @@ describe('probeServerInstance', () => { for (const fetchFn of [ jest.fn().mockRejectedValue(new TypeError('Failed to fetch')), answer('Bad Gateway', 502), + // Headers arrived, then the body was cut off. + jest.fn().mockResolvedValue({ + ok: true, + status: 200, + json: async () => { + throw new DOMException('aborted', 'AbortError'); + }, + }), ]) { await expect( probeServerInstance({ ...config, fetchFn: fetchFn as never }) diff --git a/apps/web/src/app/server-storage/server-instance-probe.ts b/apps/web/src/app/server-storage/server-instance-probe.ts index 4d7d9766c..e78338c3d 100644 --- a/apps/web/src/app/server-storage/server-instance-probe.ts +++ b/apps/web/src/app/server-storage/server-instance-probe.ts @@ -64,8 +64,11 @@ export async function probeServerInstance( return isServerInstance(body) && body.storage === 'server' ? { kind: 'server', instance: body } : { kind: 'none' }; - } catch { - return { kind: 'none' }; + } catch (error) { + // Unparseable JSON is an answer; a cut-off body is an outage. + return error instanceof SyntaxError + ? { kind: 'none' } + : { kind: 'unreachable' }; } } diff --git a/apps/web/src/app/settings/settings-server-section.component.ts b/apps/web/src/app/settings/settings-server-section.component.ts index 7da1af19c..a003016f2 100644 --- a/apps/web/src/app/settings/settings-server-section.component.ts +++ b/apps/web/src/app/settings/settings-server-section.component.ts @@ -22,8 +22,8 @@ import type { ServerStorageStatusResponse } from '@iptvnator/shared/interfaces'; /** * Settings → Server: shown only when the PWA runs against self-hosted - * server storage. Loaded with `@defer`, so other builds never fetch the - * server-storage code for the settings page. + * server storage. Rendered without `@defer` so settings search can reveal + * its rows on the first visit; the code rides in the lazy settings chunk. */ @Component({ selector: 'app-settings-server-section', diff --git a/apps/web/src/app/settings/settings.component.html b/apps/web/src/app/settings/settings.component.html index 925cb21ee..75c6702be 100644 --- a/apps/web/src/app/settings/settings.component.html +++ b/apps/web/src/app/settings/settings.component.html @@ -120,13 +120,9 @@ /> } @case ('server') { - - @defer { - - } + } @case ('backup') {