Don't throw errors in card picker (#6188)

This commit is contained in:
Bram Kragten 2020-06-19 01:26:31 +02:00 committed by GitHub
parent 16c604937e
commit cf68f25a03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 18 deletions

View File

@ -14,6 +14,7 @@ import "../cards/hui-weather-forecast-card";
import { import {
createLovelaceElement, createLovelaceElement,
getLovelaceElementClass, getLovelaceElementClass,
tryCreateLovelaceElement,
} from "./create-element-base"; } from "./create-element-base";
const ALWAYS_LOADED_TYPES = new Set([ const ALWAYS_LOADED_TYPES = new Set([
@ -52,6 +53,17 @@ const LAZY_LOAD_TYPES = {
picture: () => import("../cards/hui-picture-card"), picture: () => import("../cards/hui-picture-card"),
}; };
// This will not return an error card but will throw the error
export const tryCreateCardElement = (config: LovelaceCardConfig) =>
tryCreateLovelaceElement(
"card",
config,
ALWAYS_LOADED_TYPES,
LAZY_LOAD_TYPES,
undefined,
undefined
);
export const createCardElement = (config: LovelaceCardConfig) => export const createCardElement = (config: LovelaceCardConfig) =>
createLovelaceElement( createLovelaceElement(
"card", "card",

View File

@ -73,15 +73,8 @@ const _createElement = <T extends keyof CreateElementConfigTypes>(
const element = document.createElement( const element = document.createElement(
tag tag
) as CreateElementConfigTypes[T]["element"]; ) as CreateElementConfigTypes[T]["element"];
try { // @ts-ignore
// @ts-ignore element.setConfig(config);
element.setConfig(config);
} catch (err) {
// eslint-disable-next-line
console.error(tag, err);
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return _createErrorElement(err.message, config);
}
return element; return element;
}; };
@ -152,9 +145,37 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
domainTypes?: { _domain_not_found: string; [domain: string]: string }, domainTypes?: { _domain_not_found: string; [domain: string]: string },
// Default type if no type given. If given, entity types will not work. // Default type if no type given. If given, entity types will not work.
defaultType?: string defaultType?: string
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
try {
return tryCreateLovelaceElement(
tagSuffix,
config,
alwaysLoadTypes,
lazyLoadTypes,
domainTypes,
defaultType
);
} catch (err) {
// eslint-disable-next-line
console.error(tagSuffix, config.type, err);
return _createErrorElement(err.message, config);
}
};
export const tryCreateLovelaceElement = <
T extends keyof CreateElementConfigTypes
>(
tagSuffix: T,
config: CreateElementConfigTypes[T]["config"],
alwaysLoadTypes?: Set<string>,
lazyLoadTypes?: { [domain: string]: () => Promise<unknown> },
// Allow looking at "entity" in config and mapping that to a type
domainTypes?: { _domain_not_found: string; [domain: string]: string },
// Default type if no type given. If given, entity types will not work.
defaultType?: string
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => { ): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
if (!config || typeof config !== "object") { if (!config || typeof config !== "object") {
return _createErrorElement("Config is not an object", config); throw new Error("Config is not an object");
} }
if ( if (
@ -163,7 +184,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
// If domain types is given, we can derive a type from "entity" // If domain types is given, we can derive a type from "entity"
(!domainTypes || !("entity" in config)) (!domainTypes || !("entity" in config))
) { ) {
return _createErrorElement("No card type configured.", config); throw new Error("No card type configured.");
} }
const customTag = config.type ? _getCustomTag(config.type) : undefined; const customTag = config.type ? _getCustomTag(config.type) : undefined;
@ -185,7 +206,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
} }
if (type === undefined) { if (type === undefined) {
return _createErrorElement(`No type specified`, config); throw new Error("No type specified.");
} }
const tag = `hui-${type}-${tagSuffix}`; const tag = `hui-${type}-${tagSuffix}`;
@ -199,7 +220,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
return _createElement(tag, config); return _createElement(tag, config);
} }
return _createErrorElement(`Unknown type encountered: ${type}.`, config); throw new Error(`Unknown type encountered: ${type}`);
}; };
export const getLovelaceElementClass = async < export const getLovelaceElementClass = async <

View File

@ -27,7 +27,7 @@ import {
calcUnusedEntities, calcUnusedEntities,
computeUsedEntities, computeUsedEntities,
} from "../../common/compute-unused-entities"; } from "../../common/compute-unused-entities";
import { createCardElement } from "../../create-element/create-card-element"; import { tryCreateCardElement } from "../../create-element/create-card-element";
import { LovelaceCard } from "../../types"; import { LovelaceCard } from "../../types";
import { getCardStubConfig } from "../get-card-stub-config"; import { getCardStubConfig } from "../get-card-stub-config";
import { CardPickTarget, Card } from "../types"; import { CardPickTarget, Card } from "../types";
@ -307,8 +307,8 @@ export class HuiCardPicker extends LitElement {
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _createCardElement(cardConfig: LovelaceCardConfig) { private _tryCreateCardElement(cardConfig: LovelaceCardConfig) {
const element = createCardElement(cardConfig) as LovelaceCard; const element = tryCreateCardElement(cardConfig) as LovelaceCard;
element.hass = this.hass; element.hass = this.hass;
element.addEventListener( element.addEventListener(
"ll-rebuild", "ll-rebuild",
@ -325,7 +325,12 @@ export class HuiCardPicker extends LitElement {
cardElToReplace: LovelaceCard, cardElToReplace: LovelaceCard,
config: LovelaceCardConfig config: LovelaceCardConfig
): void { ): void {
const newCardEl = this._createCardElement(config); let newCardEl: LovelaceCard;
try {
newCardEl = this._tryCreateCardElement(config);
} catch (err) {
return;
}
if (cardElToReplace.parentElement) { if (cardElToReplace.parentElement) {
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace); cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
} }
@ -351,7 +356,11 @@ export class HuiCardPicker extends LitElement {
); );
if (showElement) { if (showElement) {
element = this._createCardElement(cardConfig); try {
element = this._tryCreateCardElement(cardConfig);
} catch (err) {
element = undefined;
}
} }
} }