Skip to content

Show error empty state when the frontend can't authenticate - #5371

Merged
bgoncal merged 1 commit into
mainfrom
fix/webview-auth-failure-empty-state
Aug 6, 2026
Merged

Show error empty state when the frontend can't authenticate#5371
bgoncal merged 1 commit into
mainfrom
fix/webview-auth-failure-empty-state

Conversation

@bgoncal

@bgoncal bgoncal commented Aug 6, 2026

Copy link
Copy Markdown
Member

AI Policy

Select exactly one option that describes AI usage in this contribution:

  • I have not used AI for this contribution.
  • AI assistance was used for this contribution.
  • AI fully generated the code for this contribution, but I've reviewed and understood it before submitting and will respond without AI during review.

Summary

When the frontend page loads from cache but the app can't hand it an access token (e.g. the server is only reachable on the local network and macOS denied the "Local Network" permission), there is no navigation error and the frontend never reports a connection state. Nothing took the stand-by loader down, so the app just kept loading forever with no way to reach the error details.

Those token failures are now treated like a failed load: the error is kept for the details screen and the disconnected empty state with "More details" shows after the usual grace period.

Also drops the platform button style from the error details link rows, which draw their own background and so showed two stacked backgrounds on Mac.

Screenshots

Link to pull request in Documentation repository

Documentation: home-assistant/companion.home-assistant#

Any other notes

Most visible on Mac, where the stand-by loader's delayed settings and clean-cache escape hatches are hidden.


Generated by Claude Code

The frontend asks the app for an access token before it can connect. When
that request keeps failing - e.g. the server is only reachable on the local
network and macOS denied the "Local Network" privacy permission - the page
itself has already loaded, so there is no navigation error, and the frontend
never reports a connection state. Nothing took the stand-by loader down and
the app appeared to load forever, with no way to reach the error details.

Report those failures to the web view controller so they are treated like a
failed load: the error is kept for the details screen and the disconnected
empty state (with "More details") shows after the usual grace period. The
Alamofire session-task wrapper is unwrapped so the details screen shows the
actionable URLError instead of the transport wrapper.

This was most visible on Mac, where the stand-by loader's delayed settings
and clean-cache escape hatches are hidden.

Also drop the platform button style from ExternalLinkButton/ActionLinkButton:
the rows draw their own background, so on Mac Catalyst the bordered style
painted a second background inside each row.
Copilot AI lite review requested due to automatic review settings August 6, 2026 15:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ensures the app exits the stand-by loader and presents the disconnected empty state (with retained error details) when the frontend can’t obtain an access token (e.g., blocked local-network access), plus fixes Mac Catalyst row background styling for external/action link buttons.

Changes:

  • Add handleExternalAuthFailure(error:) to WebViewControllerProtocol and wire it from WebViewScriptMessageHandler token-fetch failures.
  • Centralize empty-state grace-period scheduling via scheduleEmptyStateAfterGracePeriod() and reuse it for connection-state updates and external-auth failures.
  • Update ExternalLinkButton/ActionLinkButton to use .buttonStyle(.plain) and foregroundStyle to avoid double backgrounds on Mac Catalyst.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Tests/App/WebView/WebViewControllerTests.swift Adds unit tests covering external-auth failure behavior (state, error preservation, timer arming, retry behavior).
Tests/App/WebView/Mocks/MockWebViewController.swift Extends mock to satisfy the updated WebViewControllerProtocol and capture external-auth failures.
Sources/HADesignSystem/Sources/Components/ExternalLinkButton.swift Removes platform button styling artifacts on Mac Catalyst and updates styling to avoid stacked backgrounds.
Sources/App/Frontend/WebView/WebViewController/WebViewControllerProtocol.swift Adds a protocol hook for external-auth failures.
Sources/App/Frontend/WebView/WebViewController/WebViewController+ProtocolConformance.swift Reuses the new grace-period scheduler for disconnected/unknown connection states.
Sources/App/Frontend/WebView/WebViewController/WebViewController+EmptyState.swift Implements external-auth failure handling and factors out grace-period scheduling + error unwrapping.
Sources/App/Frontend/Extensions/WebViewScriptMessageHandler.swift Calls into the web view controller on getExternalAuth promise rejection so the UI can surface the failure.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

⚠️ Unused L10n strings detected

Found 5 unused localization strings in the codebase.

Click to see details
Parsing Strings.swift...
Found 2421 L10n strings

Reading all Swift source code...
Read 8596884 characters of Swift code

Checking for unused strings...
Checked 100/2421 strings...
Checked 200/2421 strings...
Checked 300/2421 strings...
Checked 400/2421 strings...
Checked 500/2421 strings...
Checked 600/2421 strings...
Checked 700/2421 strings...
Checked 800/2421 strings...
Checked 900/2421 strings...
Checked 1000/2421 strings...
Checked 1100/2421 strings...
Checked 1200/2421 strings...
Checked 1300/2421 strings...
Checked 1400/2421 strings...
Checked 1500/2421 strings...
Checked 1600/2421 strings...
Checked 1700/2421 strings...
Checked 1800/2421 strings...
Checked 1900/2421 strings...
Checked 2000/2421 strings...
Checked 2100/2421 strings...
Checked 2200/2421 strings...
Checked 2300/2421 strings...
Checked 2400/2421 strings...

================================================================================
UNUSED STRINGS REPORT
================================================================================

Found 5 unused strings:


ENTITYPICKER:
  - L10n.EntityPicker.addAll
    Key: entity_picker.add_all
    Line: 1725

WATCH:
  - L10n.Watch.Complications.Builder.colors
    Key: watch.complications.builder.colors
    Line: 6495
  - L10n.Watch.Complications.Builder.customColors
    Key: watch.complications.builder.custom_colors
    Line: 6505
  - L10n.Watch.Config.Add.Error.fetchFailed
    Key: watch.config.add.error.fetch_failed
    Line: 6710
  - L10n.Watch.Config.Assist.Error.fetchFailed
    Key: watch.config.assist.error.fetch_failed
    Line: 6738

================================================================================
Total unused: 5
================================================================================

================================================================================
Copy-paste these keys into the "Lokalise: Delete Keys" workflow (keys input):
================================================================================
entity_picker.add_all,watch.complications.builder.colors,watch.complications.builder.custom_colors,watch.config.add.error.fetch_failed,watch.config.assist.error.fetch_failed

To remove them, run the
Lokalise: Delete Keys
workflow — it deletes the keys from Lokalise and opens a PR removing them from
Localizable.strings and regenerating Strings.swift. Copy-paste these keys into the keys input:

entity_picker.add_all,watch.complications.builder.colors,watch.complications.builder.custom_colors,watch.config.add.error.fetch_failed,watch.config.assist.error.fetch_failed

@bgoncal
bgoncal merged commit 9dcd97d into main Aug 6, 2026
14 checks passed
@bgoncal
bgoncal deleted the fix/webview-auth-failure-empty-state branch August 6, 2026 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants