From 3c48157793e989d8226a091eb4c14f10146ff735 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 6 Sep 2023 09:53:54 +0200 Subject: [PATCH] Use report errors instead of strict for template subscription (#17824) --- src/data/ws-templates.ts | 19 +- .../template/developer-tools-template.ts | 185 ++++++++++-------- .../lovelace/cards/hui-markdown-card.ts | 3 +- 3 files changed, 119 insertions(+), 88 deletions(-) diff --git a/src/data/ws-templates.ts b/src/data/ws-templates.ts index ed873c69f7..ba3bcc41d3 100644 --- a/src/data/ws-templates.ts +++ b/src/data/ws-templates.ts @@ -6,6 +6,11 @@ export interface RenderTemplateResult { listeners: TemplateListeners; } +export interface RenderTemplateError { + error: string; + level: "ERROR" | "WARNING"; +} + export interface TemplateListeners { all: boolean; domains: string[]; @@ -27,19 +32,23 @@ interface TemplatePreviewError { export const subscribeRenderTemplate = ( conn: Connection, - onChange: (result: RenderTemplateResult) => void, + onChange: (result: RenderTemplateResult | RenderTemplateError) => void, params: { template: string; entity_ids?: string | string[]; variables?: Record; timeout?: number; strict?: boolean; + report_errors?: boolean; } ): Promise => - conn.subscribeMessage((msg: RenderTemplateResult) => onChange(msg), { - type: "render_template", - ...params, - }); + conn.subscribeMessage( + (msg: RenderTemplateResult | RenderTemplateError) => onChange(msg), + { + type: "render_template", + ...params, + } + ); export const subscribePreviewTemplate = ( hass: HomeAssistant, diff --git a/src/panels/developer-tools/template/developer-tools-template.ts b/src/panels/developer-tools/template/developer-tools-template.ts index 5f5d0f2122..4df882bbdb 100644 --- a/src/panels/developer-tools/template/developer-tools-template.ts +++ b/src/panels/developer-tools/template/developer-tools-template.ts @@ -4,6 +4,7 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { debounce } from "../../../common/util/debounce"; +import "../../../components/ha-alert"; import "../../../components/ha-circular-progress"; import "../../../components/ha-code-editor"; import { @@ -44,6 +45,8 @@ class HaPanelDevTemplate extends LitElement { @state() private _error?: string; + @state() private _errorLevel?: "ERROR" | "WARNING"; + @state() private _rendering = false; @state() private _templateResult?: RenderTemplateResult; @@ -157,83 +160,87 @@ class HaPanelDevTemplate extends LitElement { size="small" >` : ""} + ${this._error + ? html`${this._error}` + : nothing} ${this._templateResult ? html`${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.result_type" - )}: - ${resultType}` - : ""} - -
${this._error}${type === "object"
-            ? JSON.stringify(this._templateResult!.result, null, 2)
-            : this._templateResult?.result}
- ${this._templateResult?.listeners.time - ? html` -

- ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.time" - )} -

- ` - : nothing} - ${!this._templateResult?.listeners - ? nothing - : this._templateResult.listeners.all - ? html` -

- ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.all_listeners" - )} -

- ` - : this._templateResult.listeners.domains.length || - this._templateResult.listeners.entities.length - ? html` -

- ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.listeners" - )} -

-
    - ${this._templateResult.listeners.domains - .sort() - .map( - (domain) => html` -
  • - ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.domain" - )}: ${domain} -
  • - ` - )} - ${this._templateResult.listeners.entities - .sort() - .map( - (entity_id) => html` -
  • - ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.entity" - )}: ${entity_id} -
  • - ` - )} -
- ` - : !this._templateResult?.listeners.time - ? html` - ${this.hass.localize( - "ui.panel.developer-tools.tabs.templates.no_listeners" - )} - ` + "ui.panel.developer-tools.tabs.templates.result_type" + )}: + ${resultType} + +
${type === "object"
+                  ? JSON.stringify(this._templateResult.result, null, 2)
+                  : this._templateResult.result}
+ ${this._templateResult.listeners.time + ? html` +

+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.time" + )} +

+ ` + : ""} + ${!this._templateResult.listeners + ? nothing + : this._templateResult.listeners.all + ? html` +

+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.all_listeners" + )} +

+ ` + : this._templateResult.listeners.domains.length || + this._templateResult.listeners.entities.length + ? html` +

+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.listeners" + )} +

+
    + ${this._templateResult.listeners.domains + .sort() + .map( + (domain) => html` +
  • + ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.domain" + )}: ${domain} +
  • + ` + )} + ${this._templateResult.listeners.entities + .sort() + .map( + (entity_id) => html` +
  • + ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.entity" + )}: ${entity_id} +
  • + ` + )} +
+ ` + : !this._templateResult.listeners.time + ? html` + ${this.hass.localize( + "ui.panel.developer-tools.tabs.templates.no_listeners" + )} + ` + : nothing}` : nothing} @@ -276,6 +283,7 @@ class HaPanelDevTemplate extends LitElement { .render-pane { position: relative; max-width: 50%; + flex: 1; } .render-spinner { @@ -284,6 +292,11 @@ class HaPanelDevTemplate extends LitElement { right: 8px; } + ha-alert { + margin-bottom: 8px; + display: block; + } + .rendered { @apply --paper-font-code1; clear: both; @@ -297,10 +310,6 @@ class HaPanelDevTemplate extends LitElement { color: var(--warning-color); } - .rendered.error { - color: var(--error-color); - } - @media all and (max-width: 870px) { .render-pane { max-width: 100%; @@ -323,6 +332,7 @@ class HaPanelDevTemplate extends LitElement { this._template = ev.detail.value; if (this._error) { this._error = undefined; + this._errorLevel = undefined; } this._debounceRender(); } @@ -334,20 +344,31 @@ class HaPanelDevTemplate extends LitElement { this._unsubRenderTemplate = subscribeRenderTemplate( this.hass.connection, (result) => { - this._templateResult = result; - this._error = undefined; + if ("error" in result) { + // We show the latest error, or a warning if there are no errors + if (result.level === "ERROR" || this._errorLevel !== "ERROR") { + this._error = result.error; + this._errorLevel = result.level; + } + } else { + this._templateResult = result; + this._error = undefined; + this._errorLevel = undefined; + } }, { template: this._template, timeout: 3, - strict: true, + report_errors: true, } ); await this._unsubRenderTemplate; } catch (err: any) { this._error = "Unknown error"; + this._errorLevel = undefined; if (err.message) { this._error = err.message; + this._errorLevel = undefined; this._templateResult = undefined; } this._unsubRenderTemplate = undefined; diff --git a/src/panels/lovelace/cards/hui-markdown-card.ts b/src/panels/lovelace/cards/hui-markdown-card.ts index 0cf9f5c4e4..d527869646 100644 --- a/src/panels/lovelace/cards/hui-markdown-card.ts +++ b/src/panels/lovelace/cards/hui-markdown-card.ts @@ -127,7 +127,7 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard { this._unsubRenderTemplate = subscribeRenderTemplate( this.hass.connection, (result) => { - this._templateResult = result; + this._templateResult = result as RenderTemplateResult; }, { template: this._config.content, @@ -139,6 +139,7 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard { strict: true, } ); + await this._unsubRenderTemplate; } catch (_err) { this._templateResult = { result: this._config!.content,