Use report errors instead of strict for template subscription (#17824)

This commit is contained in:
Bram Kragten 2023-09-06 09:53:54 +02:00 committed by GitHub
parent 3a07af6ad2
commit 3c48157793
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 88 deletions

View File

@ -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<string, unknown>;
timeout?: number;
strict?: boolean;
report_errors?: boolean;
}
): Promise<UnsubscribeFunc> =>
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,

View File

@ -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"
></ha-circular-progress>`
: ""}
${this._error
? html`<ha-alert
alert-type=${this._errorLevel?.toLowerCase() || "error"}
>${this._error}</ha-alert
>`
: nothing}
${this._templateResult
? html`${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.result_type"
)}:
${resultType}`
: ""}
<!-- prettier-ignore -->
<pre
class="rendered ${classMap({
error: Boolean(this._error),
[resultType]: resultType,
})}"
>${this._error}${type === "object"
? JSON.stringify(this._templateResult!.result, null, 2)
: this._templateResult?.result}</pre>
${this._templateResult?.listeners.time
? html`
<p>
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.time"
)}
</p>
`
: nothing}
${!this._templateResult?.listeners
? nothing
: this._templateResult.listeners.all
? html`
<p class="all_listeners">
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.all_listeners"
)}
</p>
`
: this._templateResult.listeners.domains.length ||
this._templateResult.listeners.entities.length
? html`
<p>
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.listeners"
)}
</p>
<ul>
${this._templateResult.listeners.domains
.sort()
.map(
(domain) => html`
<li>
<b
>${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.domain"
)}</b
>: ${domain}
</li>
`
)}
${this._templateResult.listeners.entities
.sort()
.map(
(entity_id) => html`
<li>
<b
>${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.entity"
)}</b
>: ${entity_id}
</li>
`
)}
</ul>
`
: !this._templateResult?.listeners.time
? html`<span class="all_listeners">
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.no_listeners"
)}
</span>`
"ui.panel.developer-tools.tabs.templates.result_type"
)}:
${resultType}
<!-- prettier-ignore -->
<pre class="rendered ${classMap({
[resultType]: resultType,
})}"
>${type === "object"
? JSON.stringify(this._templateResult.result, null, 2)
: this._templateResult.result}</pre>
${this._templateResult.listeners.time
? html`
<p>
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.time"
)}
</p>
`
: ""}
${!this._templateResult.listeners
? nothing
: this._templateResult.listeners.all
? html`
<p class="all_listeners">
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.all_listeners"
)}
</p>
`
: this._templateResult.listeners.domains.length ||
this._templateResult.listeners.entities.length
? html`
<p>
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.listeners"
)}
</p>
<ul>
${this._templateResult.listeners.domains
.sort()
.map(
(domain) => html`
<li>
<b
>${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.domain"
)}</b
>: ${domain}
</li>
`
)}
${this._templateResult.listeners.entities
.sort()
.map(
(entity_id) => html`
<li>
<b
>${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.entity"
)}</b
>: ${entity_id}
</li>
`
)}
</ul>
`
: !this._templateResult.listeners.time
? html`<span class="all_listeners">
${this.hass.localize(
"ui.panel.developer-tools.tabs.templates.no_listeners"
)}
</span>`
: nothing}`
: nothing}
</div>
</div>
@ -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;

View File

@ -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,