Improve error rendering.

This commit is contained in:
Dermot Duffy
2021-08-09 21:46:39 -07:00
parent a8fab3263e
commit c1ebc1bf5e
2 changed files with 52 additions and 38 deletions
+1 -1
View File
@@ -19,7 +19,7 @@
scrollbar-width: none; // Hide scrollbar: Firefox scrollbar-width: none; // Hide scrollbar: Firefox
} }
.frigate-card-exception { .frigate-card-attention {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
+42 -28
View File
@@ -4,8 +4,6 @@
// TODO Action handlers. // TODO Action handlers.
// TODO _getEvents may throw errors, catch them when called.
// TODO Can I use Zod for FrigateCardConfig validation? // TODO Can I use Zod for FrigateCardConfig validation?
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -34,7 +32,7 @@ import './editor';
import style from './frigate-card.scss' import style from './frigate-card.scss'
import { frigateEventSchema, frigateGetEventsResponseSchema } from './types'; import { frigateGetEventsResponseSchema } from './types';
import type { FrigateCardConfig, FrigateEvent, FrigateGetEventsResponse, GetEventsParameters, ControlVideosParameters } from './types'; import type { FrigateCardConfig, FrigateEvent, FrigateGetEventsResponse, GetEventsParameters, ControlVideosParameters } from './types';
import { actionHandler } from './action-handler-directive'; import { actionHandler } from './action-handler-directive';
import { CARD_VERSION } from './const'; import { CARD_VERSION } from './const';
@@ -228,35 +226,51 @@ export class FrigateCard extends LitElement {
try { try {
raw_json = await response.json(); raw_json = await response.json();
} catch(e) { } catch(e) {
console.warn(e);
throw new Error(`Could not JSON decode Frigate API response: ${e}`); throw new Error(`Could not JSON decode Frigate API response: ${e}`);
} }
try { try {
return frigateGetEventsResponseSchema.parse(raw_json); return frigateGetEventsResponseSchema.parse(raw_json);
} catch(e) { } catch(e) {
console.warn(e);
throw new Error(`Frigate events were malformed: ${e}`); throw new Error(`Frigate events were malformed: ${e}`);
} }
} else { } else {
// TODO: Catch when json decoding fails. const error_message = `Frigate API request failed with status: ${response.status}`;
throw new Error(`Frigate API request failed with status: ${response.status}`); console.warn(error_message);
throw new Error(error_message);
} }
} }
protected _renderAttentionIcon(icon: string): TemplateResult {
return html`
<div class="frigate-card-attention">
<ha-icon icon="${icon}">
</ha-icon>
</div>`;
}
// Render an embedded error situation.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected _renderError(_error: string) : TemplateResult {
return this._renderAttentionIcon("mdi:alert-circle");
}
// Render Frigate events into a card gallery. // Render Frigate events into a card gallery.
protected async _renderEvents() : Promise<TemplateResult> { protected async _renderEvents() : Promise<TemplateResult> {
const want_clips = this._viewMode == FrigateCardView.CLIPS; const want_clips = this._viewMode == FrigateCardView.CLIPS;
let events;
const events = await this._getEvents({ try {
events = await this._getEvents({
has_clip: want_clips, has_clip: want_clips,
has_snapshot: !want_clips, has_snapshot: !want_clips,
}); });
} catch (e) {
return this._renderError(e);
}
if (!events.length) { if (!events.length) {
return html` return this._renderAttentionIcon(want_clips ? "mdi:filmstrip-off" : "mdi:camera-off");
<div class="frigate-card-exception">
<ha-icon
icon="${want_clips ? "mdi:filmstrip-off" : "mdi:camera-off"}"
></ha-icon>
</div>`
} }
return html` return html`
@@ -281,7 +295,7 @@ export class FrigateCard extends LitElement {
// Render a progress spinner while content loads. // Render a progress spinner while content loads.
protected _renderProgressIndicator(): TemplateResult { protected _renderProgressIndicator(): TemplateResult {
return html` return html`
<div class="frigate-card-exception"> <div class="frigate-card-attention">
<ha-circular-progress <ha-circular-progress
active="true" active="true"
size="large" size="large"
@@ -369,20 +383,20 @@ export class FrigateCard extends LitElement {
// Render the player for a saved clip. // Render the player for a saved clip.
protected async _renderClipPlayer(): Promise<TemplateResult> { protected async _renderClipPlayer(): Promise<TemplateResult> {
let event: FrigateEvent; let event: FrigateEvent, events: FrigateGetEventsResponse;
if (this._viewEvent) { if (this._viewEvent) {
event = this._viewEvent; event = this._viewEvent;
} else { } else {
const events = await this._getEvents({ try {
events = await this._getEvents({
has_clip: true, has_clip: true,
limit: 1 limit: 1
}); });
} catch (e) {
return this._renderError(e);
}
if (!events.length) { if (!events.length) {
return html` return this._renderAttentionIcon("mdi:camera-off");
<div class="frigate-card-exception">
<ha-icon icon="mdi:camera-off">
</ha-icon>
</div>`
} }
event = events[0]; event = events[0];
} }
@@ -396,20 +410,20 @@ export class FrigateCard extends LitElement {
// Render a snapshot. // Render a snapshot.
protected async _renderSnapshotViewer(): Promise<TemplateResult> { protected async _renderSnapshotViewer(): Promise<TemplateResult> {
let event: FrigateEvent; let event: FrigateEvent, events: FrigateGetEventsResponse;
if (this._viewEvent) { if (this._viewEvent) {
event = this._viewEvent; event = this._viewEvent;
} else { } else {
const events = await this._getEvents({ try {
events = await this._getEvents({
has_snapshot: true, has_snapshot: true,
limit: 1 limit: 1
}); });
} catch (e) {
return this._renderError(e);
}
if (!events.length) { if (!events.length) {
return html` return this._renderAttentionIcon("mdi:filmstrip-off");
<div class="frigate-card-exception">
<ha-icon icon="mdi:filmstrip-off">
</ha-icon>
</div>`
} }
event = events[0]; event = events[0];
} }