Remove unnecessary error handling parameter.

This commit is contained in:
Dermot Duffy
2023-10-02 20:31:27 -07:00
parent c2145ef0d5
commit 5ebd85e5e8
6 changed files with 128 additions and 68 deletions
+5 -8
View File
@@ -13,7 +13,7 @@ import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { DateRange } from '../camera-manager/range'; import { DateRange } from '../camera-manager/range';
import { localize } from '../localize/localize'; import { localize } from '../localize/localize';
import mediaFilterStyle from '../scss/media-filter.scss'; import mediaFilterStyle from '../scss/media-filter.scss';
import { executeMediaQueryForView } from '../utils/media-to-view.js'; import { executeMediaQueryForViewWithErrorDispatching } from '../utils/media-to-view.js';
import { errorToConsole, formatDate, prettifyTitle } from '../utils/basic'; import { errorToConsole, formatDate, prettifyTitle } from '../utils/basic';
import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin'; import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin';
import './select'; import './select';
@@ -228,7 +228,7 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
]); ]);
( (
await executeMediaQueryForView( await executeMediaQueryForViewWithErrorDispatching(
this, this,
this.cameraManager, this.cameraManager,
this.view, this.view,
@@ -251,7 +251,7 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
]); ]);
( (
await executeMediaQueryForView( await executeMediaQueryForViewWithErrorDispatching(
this, this,
this.cameraManager, this.cameraManager,
this.view, this.view,
@@ -404,7 +404,7 @@ class FrigateCardMediaFilter extends ScopedRegistryHost(LitElement) {
...(what && { what: what }), ...(what && { what: what }),
...(where && { where: where }), ...(where && { where: where }),
...(favorite !== undefined && { favorite: favorite }), ...(favorite !== undefined && { favorite: favorite }),
...(tags && { tags: tags }) ...(tags && { tags: tags }),
}; };
} }
@@ -527,10 +527,7 @@ export class MediaMetadataController implements ReactiveController {
public whatOptions: SelectOption[] = []; public whatOptions: SelectOption[] = [];
public whereOptions: SelectOption[] = []; public whereOptions: SelectOption[] = [];
constructor( constructor(host: ReactiveControllerHost, cameraManager: CameraManager) {
host: ReactiveControllerHost,
cameraManager: CameraManager,
) {
this._host = host; this._host = host;
this._cameraManager = cameraManager; this._cameraManager = cameraManager;
host.addController(this); host.addController(this);
+7 -9
View File
@@ -50,7 +50,10 @@ import {
isTruthy, isTruthy,
setOrRemoveAttribute, setOrRemoveAttribute,
} from '../utils/basic'; } from '../utils/basic';
import { executeMediaQueryForView, findBestMediaIndex } from '../utils/media-to-view'; import {
executeMediaQueryForViewWithErrorDispatching,
findBestMediaIndex,
} from '../utils/media-to-view';
import { FrigateCardTimelineItem, TimelineDataSource } from '../utils/timeline-source'; import { FrigateCardTimelineItem, TimelineDataSource } from '../utils/timeline-source';
import { ViewMedia } from '../view/media'; import { ViewMedia } from '../view/media';
import { ViewMediaClassifier } from '../view/media-classifier'; import { ViewMediaClassifier } from '../view/media-classifier';
@@ -580,7 +583,7 @@ export class FrigateCardTimelineCore extends LitElement {
) { ) {
const query = this._createMediaQueries('recording'); const query = this._createMediaQueries('recording');
if (query) { if (query) {
view = await executeMediaQueryForView( view = await executeMediaQueryForViewWithErrorDispatching(
this, this,
this.cameraManager, this.cameraManager,
this.view, this.view,
@@ -734,7 +737,7 @@ export class FrigateCardTimelineCore extends LitElement {
if (!this.hass || !this.cameraManager || !this.view || !query) { if (!this.hass || !this.cameraManager || !this.view || !query) {
return null; return null;
} }
const view = await executeMediaQueryForView( const view = await executeMediaQueryForViewWithErrorDispatching(
this, this,
this.cameraManager, this.cameraManager,
this.view, this.view,
@@ -971,12 +974,7 @@ export class FrigateCardTimelineCore extends LitElement {
* Update the timeline from the view object. * Update the timeline from the view object.
*/ */
protected async _updateTimelineFromView(): Promise<void> { protected async _updateTimelineFromView(): Promise<void> {
if ( if (!this.view || !this.timelineConfig || !this._timelineSource || !this._timeline) {
!this.view ||
!this.timelineConfig ||
!this._timelineSource ||
!this._timeline
) {
return; return;
} }
+6 -3
View File
@@ -101,7 +101,6 @@ export class ViewManager {
} }
public async setViewWithNewDisplayMode(displayMode: ViewDisplayMode): Promise<void> { public async setViewWithNewDisplayMode(displayMode: ViewDisplayMode): Promise<void> {
const host = this._api.getCardElementManager().getElement();
const hass = this._api.getHASSManager().getHASS(); const hass = this._api.getHASSManager().getHASS();
if (this._view && hass) { if (this._view && hass) {
@@ -125,8 +124,9 @@ export class ViewManager {
// query for more than one camera, reset the query results, change the // query for more than one camera, reset the query results, change the
// existing query to refer to all cameras and execute it to fetch new // existing query to refer to all cameras and execute it to fetch new
// results. // results.
const viewWithNewQuery = await executeMediaQueryForView( let viewWithNewQuery: View | null = null;
host, try {
viewWithNewQuery = await executeMediaQueryForView(
this._api.getCameraManager(), this._api.getCameraManager(),
view, view,
view.query view.query
@@ -137,6 +137,9 @@ export class ViewManager {
: view.camera, : view.camera,
), ),
); );
} catch (e: unknown) {
this._api.getMessageManager().setErrorIfHigherPriority(e);
}
if (viewWithNewQuery) { if (viewWithNewQuery) {
return this._setView(viewWithNewQuery); return this._setView(viewWithNewQuery);
+43 -15
View File
@@ -44,10 +44,16 @@ export const changeViewToRecentEventsForCameraAndDependents = async (
} }
( (
await executeMediaQueryForView(element, cameraManager, view, queries, { await executeMediaQueryForViewWithErrorDispatching(
element,
cameraManager,
view,
queries,
{
targetView: options?.targetView, targetView: options?.targetView,
select: options?.select, select: options?.select,
}) },
)
)?.dispatchChangeEvent(element); )?.dispatchChangeEvent(element);
}; };
@@ -106,10 +112,16 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
} }
( (
await executeMediaQueryForView(element, cameraManager, view, queries, { await executeMediaQueryForViewWithErrorDispatching(
element,
cameraManager,
view,
queries,
{
targetView: options?.targetView, targetView: options?.targetView,
select: options?.select, select: options?.select,
}) },
)
)?.dispatchChangeEvent(element); )?.dispatchChangeEvent(element);
}; };
@@ -127,7 +139,6 @@ const createQueriesForRecordingsView = (
}; };
export const executeMediaQueryForView = async ( export const executeMediaQueryForView = async (
element: HTMLElement,
cameraManager: CameraManager, cameraManager: CameraManager,
view: View, view: View,
query: MediaQueries, query: MediaQueries,
@@ -138,21 +149,12 @@ export const executeMediaQueryForView = async (
select?: ResultSelectType; select?: ResultSelectType;
}, },
): Promise<View | null> => { ): Promise<View | null> => {
let mediaArray: ViewMedia[] | null;
const queries = query.getQueries(); const queries = query.getQueries();
if (!queries) { if (!queries) {
return null; return null;
} }
try { const mediaArray = await cameraManager.executeMediaQueries<MediaQuery>(queries);
mediaArray = await cameraManager.executeMediaQueries<MediaQuery>(queries);
} catch (e) {
errorToConsole(e as Error);
dispatchFrigateCardErrorEvent(element, e as Error);
return null;
}
if (!mediaArray) { if (!mediaArray) {
return null; return null;
} }
@@ -182,6 +184,32 @@ export const executeMediaQueryForView = async (
.mergeInContext(viewerContext); .mergeInContext(viewerContext);
}; };
export const executeMediaQueryForViewWithErrorDispatching = async (
element: HTMLElement,
cameraManager: CameraManager,
view: View,
query: MediaQueries,
options?: {
targetCameraID?: string;
targetView?: FrigateCardView;
targetTime?: Date;
select?: ResultSelectType;
},
): Promise<View | null> => {
try {
return await executeMediaQueryForView(cameraManager, view, query, {
targetCameraID: options?.targetCameraID,
targetView: options?.targetView,
targetTime: options?.targetTime,
select: options?.select,
});
} catch (e: unknown) {
errorToConsole(e as Error);
dispatchFrigateCardErrorEvent(element, e as Error);
}
return null;
};
/** /**
* Find the longest matching media object that contains a given targetTime. * Find the longest matching media object that contains a given targetTime.
* Longest is chosen to give the most stability to the media viewer. * Longest is chosen to give the most stability to the media viewer.
@@ -496,7 +496,7 @@ describe('ViewManager.setViewWithNewDisplayMode', () => {
manager.setView(originalView); manager.setView(originalView);
// Query execution fails / returns null. // Query execution fails / returns null.
vi.mocked(cameraManager.executeMediaQueries).mockResolvedValue(null); vi.mocked(cameraManager.executeMediaQueries).mockRejectedValue(null);
await manager.setViewWithNewDisplayMode('single'); await manager.setViewWithNewDisplayMode('single');
+40 -6
View File
@@ -6,6 +6,7 @@ import {
changeViewToRecentEventsForCameraAndDependents, changeViewToRecentEventsForCameraAndDependents,
changeViewToRecentRecordingForCameraAndDependents, changeViewToRecentRecordingForCameraAndDependents,
executeMediaQueryForView, executeMediaQueryForView,
executeMediaQueryForViewWithErrorDispatching,
findBestMediaIndex, findBestMediaIndex,
} from '../../src/utils/media-to-view'; } from '../../src/utils/media-to-view';
import { ViewMedia } from '../../src/view/media'; import { ViewMedia } from '../../src/view/media';
@@ -205,13 +206,11 @@ describe('executeMediaQueryForView', () => {
}); });
it('should not execute empty queries', async () => { it('should not execute empty queries', async () => {
const elementHandler = createElementListenForView();
const cameraConfigs: CameraConfigs = new Map(); const cameraConfigs: CameraConfigs = new Map();
const cameraManager = createCameraManager({ configs: cameraConfigs }); const cameraManager = createCameraManager({ configs: cameraConfigs });
expect( expect(
await executeMediaQueryForView( await executeMediaQueryForView(
elementHandler.element,
cameraManager, cameraManager,
createView(), createView(),
new EventMediaQueries(), new EventMediaQueries(),
@@ -219,8 +218,23 @@ describe('executeMediaQueryForView', () => {
).toBeNull(); ).toBeNull();
}); });
it('should throw on failure', async () => {
const cameraConfigs: CameraConfigs = new Map();
const cameraManager = createCameraManager({ configs: cameraConfigs });
vi.mocked(cameraManager.executeMediaQueries).mockRejectedValue(new Error());
await expect(
executeMediaQueryForView(
cameraManager,
createView(),
new EventMediaQueries(
cameraManager.generateDefaultEventQueries('camera') ?? undefined,
),
),
).rejects.toThrowError();
});
it('should select time-based result', async () => { it('should select time-based result', async () => {
const elementHandler = createElementListenForView();
const cameraConfigs: CameraConfigs = new Map(); const cameraConfigs: CameraConfigs = new Map();
const cameraManager = createCameraManager({ configs: cameraConfigs }); const cameraManager = createCameraManager({ configs: cameraConfigs });
@@ -233,7 +247,6 @@ describe('executeMediaQueryForView', () => {
vi.mocked(cameraManager.executeMediaQueries).mockResolvedValue(mediaArray); vi.mocked(cameraManager.executeMediaQueries).mockResolvedValue(mediaArray);
const view = await executeMediaQueryForView( const view = await executeMediaQueryForView(
elementHandler.element,
cameraManager, cameraManager,
createView(), createView(),
new EventMediaQueries( new EventMediaQueries(
@@ -251,7 +264,6 @@ describe('executeMediaQueryForView', () => {
}); });
it('should select nothing when time-based selection does not match', async () => { it('should select nothing when time-based selection does not match', async () => {
const elementHandler = createElementListenForView();
const cameraConfigs: CameraConfigs = new Map(); const cameraConfigs: CameraConfigs = new Map();
const cameraManager = createCameraManager({ configs: cameraConfigs }); const cameraManager = createCameraManager({ configs: cameraConfigs });
@@ -265,7 +277,6 @@ describe('executeMediaQueryForView', () => {
vi.mocked(cameraManager.executeMediaQueries).mockResolvedValue(mediaArray); vi.mocked(cameraManager.executeMediaQueries).mockResolvedValue(mediaArray);
const view = await executeMediaQueryForView( const view = await executeMediaQueryForView(
elementHandler.element,
cameraManager, cameraManager,
createView(), createView(),
new EventMediaQueries( new EventMediaQueries(
@@ -378,6 +389,29 @@ describe('changeViewToRecentRecordingForCameraAndDependents', () => {
}); });
}); });
// @vitest-environment jsdom
describe('executeMediaQueryForViewWithErrorDispatching', () => {
it('should dispatch error message on fail', async () => {
vi.spyOn(global.console, 'warn').mockImplementation(() => true);
const elementHandler = createElementListenForView();
const cameraManager = createCameraManager();
vi.mocked(cameraManager.executeMediaQueries).mockRejectedValue(new Error());
await executeMediaQueryForViewWithErrorDispatching(
elementHandler.element,
cameraManager,
createView(),
new EventMediaQueries(
cameraManager.generateDefaultEventQueries('camera') ?? undefined,
),
);
expect(elementHandler.viewHandler).not.toBeCalled();
expect(elementHandler.messageHandler).toBeCalled();
});
});
// @vitest-environment jsdom // @vitest-environment jsdom
describe('findBestMediaIndex', () => { describe('findBestMediaIndex', () => {
it('should find best media index', async () => { it('should find best media index', async () => {