fix: Log problems to the console as warnings (once) (#2414)
This commit is contained in:
committed by
dermotduffy
parent
3f5a35c7f6
commit
16ca8d79d2
@@ -16,6 +16,7 @@ import {
|
|||||||
export class ProblemManager {
|
export class ProblemManager {
|
||||||
private _api: CardProblemAPI;
|
private _api: CardProblemAPI;
|
||||||
private _problems = new Map<ProblemKey, Problem>();
|
private _problems = new Map<ProblemKey, Problem>();
|
||||||
|
private _loggedKeys = new Set<ProblemKey>();
|
||||||
|
|
||||||
constructor(api: CardProblemAPI) {
|
constructor(api: CardProblemAPI) {
|
||||||
this._api = api;
|
this._api = api;
|
||||||
@@ -46,6 +47,7 @@ export class ProblemManager {
|
|||||||
public async detectStatic(hass: HomeAssistant): Promise<void> {
|
public async detectStatic(hass: HomeAssistant): Promise<void> {
|
||||||
for (const problem of this._problems.values()) {
|
for (const problem of this._problems.values()) {
|
||||||
await problem.detectStatic?.(hass);
|
await problem.detectStatic?.(hass);
|
||||||
|
this._logIfNew(problem);
|
||||||
}
|
}
|
||||||
this._api.getCardElementManager().update();
|
this._api.getCardElementManager().update();
|
||||||
}
|
}
|
||||||
@@ -122,9 +124,20 @@ export class ProblemManager {
|
|||||||
const hadResult = problem.hasResult();
|
const hadResult = problem.hasResult();
|
||||||
problem.detectDynamic?.(context);
|
problem.detectDynamic?.(context);
|
||||||
stateChanged ||= problem.hasResult() !== hadResult;
|
stateChanged ||= problem.hasResult() !== hadResult;
|
||||||
|
this._logIfNew(problem);
|
||||||
}
|
}
|
||||||
if (stateChanged) {
|
if (stateChanged) {
|
||||||
this._api.getCardElementManager().update();
|
this._api.getCardElementManager().update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _logIfNew(problem: Problem): void {
|
||||||
|
if (problem.hasResult() && !this._loggedKeys.has(problem.key)) {
|
||||||
|
this._loggedKeys.add(problem.key);
|
||||||
|
const text = problem.getResult()?.notification.text;
|
||||||
|
if (text) {
|
||||||
|
console.warn(`Advanced Camera Card: ${text}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -826,12 +826,12 @@
|
|||||||
"troubleshooting_guide": "Troubleshooting guide",
|
"troubleshooting_guide": "Troubleshooting guide",
|
||||||
"config_upgrade": {
|
"config_upgrade": {
|
||||||
"heading": "Configuration upgrade available",
|
"heading": "Configuration upgrade available",
|
||||||
"text": "A configuration upgrade is available. To upgrade, edit this card (Dashboard pencil icon \u2192 Three-dot menu \u2192 Edit) and click the 'Automatic Upgrade' button in the card editor."
|
"text": "A configuration upgrade is available. To upgrade, edit this card (Dashboard pencil icon \u2192 Three-dot menu \u2192 Edit) and click the 'Automatic Upgrade' button in the card editor"
|
||||||
},
|
},
|
||||||
"legacy_resource": {
|
"legacy_resource": {
|
||||||
"heading": "Legacy dashboard resource detected",
|
"heading": "Legacy dashboard resource detected",
|
||||||
"text_both": "The legacy 'frigate-hass-card.js' resource is still registered, please either manually remove it or click the delete icon to automatically remove it. It will be removed in a future release.",
|
"text_both": "The legacy 'frigate-hass-card.js' resource is still registered, please either manually remove it or click the delete icon to automatically remove it. It will be removed in a future release",
|
||||||
"text_only_legacy": "The legacy 'frigate-hass-card.js' resource must be replaced with 'advanced-camera-card.js'. It will be removed in a future release.",
|
"text_only_legacy": "The legacy 'frigate-hass-card.js' resource must be replaced with 'advanced-camera-card.js'. It will be removed in a future release",
|
||||||
"remove": "Remove legacy resource"
|
"remove": "Remove legacy resource"
|
||||||
},
|
},
|
||||||
"stream_not_loading": {
|
"stream_not_loading": {
|
||||||
|
|||||||
@@ -274,6 +274,72 @@ describe('ProblemManager', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('logging', () => {
|
||||||
|
it('should log on static detection when problem is active', async () => {
|
||||||
|
const spy = vi.spyOn(console, 'warn').mockReturnValue();
|
||||||
|
const api = createCardAPI();
|
||||||
|
const result = createProblemResult({ notification: { text: 'Legacy problem' } });
|
||||||
|
vi.mocked(mockLegacyResource.hasResult).mockReturnValue(true);
|
||||||
|
vi.mocked(mockLegacyResource.getResult).mockReturnValue(result);
|
||||||
|
|
||||||
|
const manager = new ProblemManager(api);
|
||||||
|
await manager.detectStatic(createHASS());
|
||||||
|
|
||||||
|
expect(spy).toBeCalledWith('Advanced Camera Card: Legacy problem');
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log on dynamic detection when problem becomes active', () => {
|
||||||
|
const spy = vi.spyOn(console, 'warn').mockReturnValue();
|
||||||
|
const api = createCardAPI();
|
||||||
|
const stateManager = new ConditionStateManager();
|
||||||
|
vi.mocked(api.getConditionStateManager).mockReturnValue(stateManager);
|
||||||
|
|
||||||
|
const result = createProblemResult({
|
||||||
|
notification: { text: 'Stream problem' },
|
||||||
|
});
|
||||||
|
vi.mocked(mockStreamNotLoading.hasResult)
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
.mockReturnValue(true);
|
||||||
|
vi.mocked(mockStreamNotLoading.getResult).mockReturnValue(result);
|
||||||
|
|
||||||
|
const manager = new ProblemManager(api);
|
||||||
|
manager.initialize();
|
||||||
|
|
||||||
|
stateManager.setState({ view: 'live' });
|
||||||
|
|
||||||
|
expect(spy).toBeCalledWith('Advanced Camera Card: Stream problem');
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only log once per problem key', async () => {
|
||||||
|
const spy = vi.spyOn(console, 'warn').mockReturnValue();
|
||||||
|
const api = createCardAPI();
|
||||||
|
const result = createProblemResult({ notification: { text: 'Repeated' } });
|
||||||
|
vi.mocked(mockLegacyResource.hasResult).mockReturnValue(true);
|
||||||
|
vi.mocked(mockLegacyResource.getResult).mockReturnValue(result);
|
||||||
|
|
||||||
|
const manager = new ProblemManager(api);
|
||||||
|
await manager.detectStatic(createHASS());
|
||||||
|
await manager.detectStatic(createHASS());
|
||||||
|
|
||||||
|
expect(spy).toBeCalledTimes(1);
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not log when problem has no result', async () => {
|
||||||
|
const spy = vi.spyOn(console, 'warn').mockReturnValue();
|
||||||
|
const api = createCardAPI();
|
||||||
|
vi.mocked(mockLegacyResource.hasResult).mockReturnValue(false);
|
||||||
|
|
||||||
|
const manager = new ProblemManager(api);
|
||||||
|
await manager.detectStatic(createHASS());
|
||||||
|
|
||||||
|
expect(spy).not.toBeCalled();
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('destroy', () => {
|
describe('destroy', () => {
|
||||||
it('should destroy all problems and clear', () => {
|
it('should destroy all problems and clear', () => {
|
||||||
const api = createCardAPI();
|
const api = createCardAPI();
|
||||||
|
|||||||
Reference in New Issue
Block a user