Fix broken cards being able to crash entire view (#11440)

This commit is contained in:
Thomas Lovén 2022-04-25 14:37:32 +02:00 committed by GitHub
parent 94953ddf6c
commit a8c365edc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 12 deletions

View File

@ -1,4 +1,4 @@
export const promiseTimeout = (ms: number, promise: Promise<any>) => {
export const promiseTimeout = (ms: number, promise: Promise<any> | any) => {
const timeout = new Promise((_resolve, reject) => {
setTimeout(() => {
reject(`Timed out in ${ms} ms.`);

View File

@ -1,10 +1,17 @@
import { promiseTimeout } from "../../../common/util/promise-timeout";
import { LovelaceCard, LovelaceHeaderFooter } from "../types";
export const computeCardSize = (
card: LovelaceCard | LovelaceHeaderFooter
): number | Promise<number> => {
if (typeof card.getCardSize === "function") {
return card.getCardSize();
try {
return promiseTimeout(500, card.getCardSize()).catch(
() => 1
) as Promise<number>;
} catch (_e: any) {
return 1;
}
}
if (customElements.get(card.localName)) {
return 1;

View File

@ -10,10 +10,18 @@ import type {
LovelaceViewElement,
} from "../../../data/lovelace";
import type { HomeAssistant } from "../../../types";
import {
createErrorBadgeConfig,
createErrorBadgeElement,
} from "../badges/hui-error-badge";
import type { HuiErrorCard } from "../cards/hui-error-card";
import { processConfigEntities } from "../common/process-config-entities";
import { createBadgeElement } from "../create-element/create-badge-element";
import { createCardElement } from "../create-element/create-card-element";
import {
createErrorCardConfig,
createErrorCardElement,
} from "../create-element/create-element-base";
import { createViewElement } from "../create-element/create-view-element";
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
@ -54,7 +62,13 @@ export class HUIView extends ReactiveElement {
// Public to make demo happy
public createCardElement(cardConfig: LovelaceCardConfig) {
const element = createCardElement(cardConfig) as LovelaceCard;
element.hass = this.hass;
try {
element.hass = this.hass;
} catch (e: any) {
return createErrorCardElement(
createErrorCardConfig(e.message, cardConfig)
);
}
element.addEventListener(
"ll-rebuild",
(ev: Event) => {
@ -71,7 +85,11 @@ export class HUIView extends ReactiveElement {
public createBadgeElement(badgeConfig: LovelaceBadgeConfig) {
const element = createBadgeElement(badgeConfig) as LovelaceBadge;
element.hass = this.hass;
try {
element.hass = this.hass;
} catch (e: any) {
return createErrorBadgeElement(createErrorBadgeConfig(e.message));
}
element.addEventListener(
"ll-badge-rebuild",
() => {
@ -121,11 +139,19 @@ export class HUIView extends ReactiveElement {
// Config has not changed. Just props
if (changedProperties.has("hass")) {
this._badges.forEach((badge) => {
badge.hass = this.hass;
try {
badge.hass = this.hass;
} catch (e: any) {
this._rebuildBadge(badge, createErrorBadgeConfig(e.message));
}
});
this._cards.forEach((element) => {
element.hass = this.hass;
try {
element.hass = this.hass;
} catch (e: any) {
this._rebuildCard(element, createErrorCardConfig(e.message, null));
}
});
this._layoutElement.hass = this.hass;
@ -238,7 +264,11 @@ export class HUIView extends ReactiveElement {
const badges = processConfigEntities(config.badges as any);
this._badges = badges.map((badge) => {
const element = createBadgeElement(badge);
element.hass = this.hass;
try {
element.hass = this.hass;
} catch (e: any) {
return createErrorBadgeElement(createErrorBadgeConfig(e.message));
}
return element;
});
}
@ -251,7 +281,13 @@ export class HUIView extends ReactiveElement {
this._cards = config.cards.map((cardConfig) => {
const element = this.createCardElement(cardConfig);
element.hass = this.hass;
try {
element.hass = this.hass;
} catch (e: any) {
return createErrorCardElement(
createErrorCardConfig(e.message, cardConfig)
);
}
return element;
});
}
@ -260,8 +296,14 @@ export class HUIView extends ReactiveElement {
cardElToReplace: LovelaceCard,
config: LovelaceCardConfig
): void {
const newCardEl = this.createCardElement(config);
newCardEl.hass = this.hass;
let newCardEl = this.createCardElement(config);
try {
newCardEl.hass = this.hass;
} catch (e: any) {
newCardEl = createErrorCardElement(
createErrorCardConfig(e.message, config)
);
}
if (cardElToReplace.parentElement) {
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
}
@ -274,8 +316,12 @@ export class HUIView extends ReactiveElement {
badgeElToReplace: LovelaceBadge,
config: LovelaceBadgeConfig
): void {
const newBadgeEl = this.createBadgeElement(config);
newBadgeEl.hass = this.hass;
let newBadgeEl = this.createBadgeElement(config);
try {
newBadgeEl.hass = this.hass;
} catch (e: any) {
newBadgeEl = createErrorBadgeElement(createErrorBadgeConfig(e.message));
}
if (badgeElToReplace.parentElement) {
badgeElToReplace.parentElement!.replaceChild(
newBadgeEl,