Skip to content

Commit bb39b56

Browse files
authored
[fix]: Get rid of unnecessary alias error (#2859)
* fixed the alias subscription error log - and made addAliasSubscribe more readable + full async * also get rid of cb of removeAliasSubscribe * add the target after the source is set
1 parent 54fd568 commit bb39b56

File tree

3 files changed

+93
-136
lines changed

3 files changed

+93
-136
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
-->
66

77
## __WORK IN PROGRESS__
8+
* (foxriver76) fixed "alias subscription error" log
89
* (foxriver76) do not check for OS updates on Docker installations
910
* (foxriver76) clear package update notification if no updates are present anymore
1011
* (Gaspode69) fixed restarting controller on Windows systems

packages/adapter/src/lib/_Types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export interface InternalFormatDateOptions {
200200
}
201201

202202
export interface AliasDetails {
203-
source: AliasDetailsSource | null;
203+
source?: AliasDetailsSource;
204204
targets: AliasTargetEntry[];
205205
}
206206

packages/adapter/src/lib/adapter/adapter.ts

Lines changed: 91 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -7849,7 +7849,7 @@ export class AdapterClass extends EventEmitter {
78497849
aliasId,
78507850
tools.formatAliasValue({
78517851
sourceCommon: obj?.common,
7852-
targetCommon: targetObj?.common as any,
7852+
targetCommon: targetObj?.common,
78537853
state: stateObj as ioBroker.State,
78547854
logger: this._logger,
78557855
logNamespace: this.namespaceLog,
@@ -9600,125 +9600,101 @@ export class AdapterClass extends EventEmitter {
96009600
}
96019601
}
96029602

9603-
private async _addAliasSubscribe(
9604-
aliasObj: ioBroker.StateObject,
9605-
pattern: string,
9606-
callback?: ioBroker.ErrorCallback
9607-
): Promise<void> {
9608-
if (aliasObj?.common?.alias?.id) {
9609-
if (aliasObj.type !== 'state') {
9610-
this._logger.warn(
9611-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
9612-
`${this.namespaceLog} Expected alias ${aliasObj._id} to be of type "state", got "${aliasObj.type}"`
9613-
);
9614-
return tools.maybeCallbackWithError(
9615-
callback,
9616-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
9617-
new Error(`Expected alias ${aliasObj._id} to be of type "state", got "${aliasObj.type}"`)
9618-
);
9619-
}
9603+
/**
9604+
* Add subscription for given alias, if it is not a state it will be ignored
9605+
*
9606+
* @param aliasObj the alias object
9607+
* @param pattern pattern to subscribe for
9608+
*/
9609+
private async _addAliasSubscribe(aliasObj: ioBroker.AnyObject, pattern: string): Promise<void> {
9610+
if (aliasObj.type !== 'state') {
9611+
// no state types do not need to be subscribed
9612+
return;
9613+
}
96209614

9621-
// id can be string or can have attribute read
9622-
const sourceId = tools.isObject(aliasObj.common.alias.id)
9623-
? aliasObj.common.alias.id.read
9624-
: aliasObj.common.alias.id;
9615+
if (!aliasObj.common?.alias?.id) {
9616+
// if state and no id given
9617+
this._logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);
9618+
throw new Error(`Alias ${aliasObj._id} has no target`);
9619+
}
96259620

9626-
// validate here because we use objects/states db directly
9627-
try {
9628-
this._utils.validateId(sourceId, true, null);
9629-
} catch (e) {
9630-
this._logger.warn(`${this.namespaceLog} Error validating alias id of ${aliasObj._id}: ${e.message}`);
9631-
return tools.maybeCallbackWithError(
9632-
callback,
9633-
new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`)
9634-
);
9635-
}
9621+
// id can be string or can have attribute read
9622+
const sourceId = tools.isObject(aliasObj.common.alias.id)
9623+
? aliasObj.common.alias.id.read
9624+
: aliasObj.common.alias.id;
96369625

9637-
let aliasDetails;
9638-
if (!this.aliases.has(sourceId)) {
9639-
aliasDetails = { source: null, targets: [] };
9640-
this.aliases.set(sourceId, aliasDetails);
9641-
} else {
9642-
aliasDetails = this.aliases.get(sourceId) || { source: null, targets: [] };
9643-
}
9626+
// validate here because we use objects/states db directly
9627+
try {
9628+
this._utils.validateId(sourceId, true, null);
9629+
} catch (e) {
9630+
throw new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`);
9631+
}
96449632

9645-
const targetEntry = {
9646-
alias: deepClone(aliasObj.common.alias),
9647-
id: aliasObj._id,
9648-
pattern,
9649-
type: aliasObj.common.type,
9650-
max: aliasObj.common.max,
9651-
min: aliasObj.common.min,
9652-
unit: aliasObj.common.unit
9653-
};
9633+
const targetEntry = {
9634+
alias: deepClone(aliasObj.common.alias),
9635+
id: aliasObj._id,
9636+
pattern,
9637+
type: aliasObj.common.type,
9638+
max: aliasObj.common.max,
9639+
min: aliasObj.common.min,
9640+
unit: aliasObj.common.unit
9641+
};
96549642

9655-
aliasDetails.targets.push(targetEntry);
9643+
let aliasDetails: AliasDetails;
96569644

9657-
if (!aliasDetails.source) {
9658-
let sourceObj;
9659-
try {
9660-
await this.#states!.subscribe(sourceId);
9661-
// we ignore permissions on the source object and thus get it as admin user
9662-
sourceObj = await this.#objects!.getObject(sourceId, { user: SYSTEM_ADMIN_USER });
9663-
} catch (e) {
9664-
return tools.maybeCallbackWithError(callback, e);
9665-
}
9645+
if (!this.aliases.has(sourceId)) {
9646+
aliasDetails = { targets: [] };
9647+
// add the alias before doing anything async, so if a delete comes in between we can detect it
9648+
this.aliases.set(sourceId, aliasDetails);
9649+
} else {
9650+
aliasDetails = this.aliases.get(sourceId)!;
9651+
}
96669652

9667-
if (sourceObj?.common) {
9668-
if (!this.aliases.has(sourceObj._id)) {
9669-
// TODO what means this, we ensured alias existed, did some async stuff now it's gone -> alias has been deleted?
9670-
this._logger.error(
9671-
`${
9672-
this.namespaceLog
9673-
} Alias subscription error. Please check your alias definitions: sourceId=${sourceId}, sourceObj=${JSON.stringify(
9674-
sourceObj
9675-
)}`
9676-
);
9677-
} else {
9678-
aliasDetails.source = {
9679-
min: sourceObj.common.min,
9680-
max: sourceObj.common.max,
9681-
type: sourceObj.common.type,
9682-
unit: sourceObj.common.unit
9683-
};
9684-
}
9685-
}
9653+
if (!aliasDetails.source) {
9654+
await this.#states!.subscribe(sourceId);
9655+
// we ignore permissions on the source object and thus get it as admin user
9656+
const sourceObj = await this.#objects!.getObject(sourceId, { user: SYSTEM_ADMIN_USER });
96869657

9687-
return tools.maybeCallback(callback);
9688-
} else {
9689-
return tools.maybeCallback(callback);
9658+
// if we have a common and the alias has not been removed in-between
9659+
if (sourceObj?.common && this.aliases.has(sourceObj._id)) {
9660+
aliasDetails.source = {
9661+
min: sourceObj.common.min,
9662+
max: sourceObj.common.max,
9663+
type: sourceObj.common.type,
9664+
unit: sourceObj.common.unit
9665+
};
96909666
}
9691-
} else if (aliasObj && aliasObj.type === 'state') {
9692-
// if state and no id given -> if no state just ignore it
9693-
this._logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);
9694-
return tools.maybeCallbackWithError(callback, new Error(`Alias ${aliasObj._id} has no target`));
9695-
} else {
9696-
return tools.maybeCallback(callback);
96979667
}
9668+
9669+
// add the alias target after we have ensured that we have the source set
9670+
aliasDetails.targets.push(targetEntry);
96989671
}
96999672

9700-
private async _removeAliasSubscribe(
9701-
sourceId: string,
9702-
aliasObj: number | AliasTargetEntry,
9703-
callback?: () => void
9704-
): Promise<void> {
9673+
/**
9674+
* Remove an alias subscribe
9675+
*
9676+
* @param sourceId id of the source object
9677+
* @param aliasObjOrIdx the alias target or the index of the targets array
9678+
*/
9679+
private async _removeAliasSubscribe(sourceId: string, aliasObjOrIdx: number | AliasTargetEntry): Promise<void> {
97059680
if (!this.aliases.has(sourceId)) {
9706-
return tools.maybeCallback(callback);
9681+
return;
97079682
}
97089683

9684+
const alias = this.aliases.get(sourceId)!;
9685+
97099686
// remove from targets array
9710-
const pos = typeof aliasObj === 'number' ? aliasObj : this.aliases.get(sourceId)!.targets.indexOf(aliasObj);
9687+
const pos = typeof aliasObjOrIdx === 'number' ? aliasObjOrIdx : alias.targets.indexOf(aliasObjOrIdx);
97119688

97129689
if (pos !== -1) {
9713-
this.aliases.get(sourceId)!.targets.splice(pos, 1);
9690+
alias.targets.splice(pos, 1);
97149691

97159692
// unsubscribe if no more aliases exists
9716-
if (!this.aliases.get(sourceId)!.targets.length) {
9693+
if (!alias.targets.length) {
97179694
this.aliases.delete(sourceId);
97189695
await this.#states!.unsubscribe(sourceId);
97199696
}
97209697
}
9721-
return tools.maybeCallback(callback);
97229698
}
97239699

97249700
subscribeForeignStates(pattern: Pattern, callback?: ioBroker.ErrorCallback): void;
@@ -9852,8 +9828,7 @@ export class AdapterClass extends EventEmitter {
98529828

98539829
for (const aliasObj of aliasObjs) {
98549830
if (aliasObj) {
9855-
// @ts-expect-error check if alias subscribe also takes non-state objects and then ignores
9856-
promises.push(new Promise(resolve => this._addAliasSubscribe(aliasObj, aliasObj._id, resolve)));
9831+
promises.push(this._addAliasSubscribe(aliasObj, aliasObj._id));
98579832
}
98589833
}
98599834
}
@@ -9891,8 +9866,7 @@ export class AdapterClass extends EventEmitter {
98919866
// If alias
98929867
if (id.startsWith(ALIAS_STARTS_WITH)) {
98939868
const aliasObj = objs[id];
9894-
// @ts-expect-error
9895-
promises.push(new Promise(resolve => this._addAliasSubscribe(aliasObj, pattern, resolve)));
9869+
promises.push(this._addAliasSubscribe(aliasObj, pattern));
98969870
}
98979871
}
98989872

@@ -9929,26 +9903,12 @@ export class AdapterClass extends EventEmitter {
99299903
this.#objects.subscribe(`${ALIAS_STARTS_WITH}*`);
99309904
}
99319905

9932-
// aliases['sourceId'] = {
9933-
// source: {common attributes},
9934-
// targets: [
9935-
// {
9936-
// alias: {},
9937-
// id: 'aliasId',
9938-
// pattern: 'some pattern',
9939-
// type: stateType,
9940-
// max: number,
9941-
// min: number,
9942-
// }
9943-
// ]
9944-
// };
9945-
99469906
// just read one alias Object
99479907
try {
9948-
const aliasObj = await this.#objects.getObjectAsync(pattern, options);
9908+
const aliasObj = await this.#objects.getObject(pattern, options);
99499909
if (aliasObj) {
9950-
// cb will be called, but await for catching promisified part
9951-
await this._addAliasSubscribe(aliasObj as ioBroker.StateObject, pattern, callback);
9910+
await this._addAliasSubscribe(aliasObj, pattern);
9911+
return tools.maybeCallback(callback);
99529912
} else {
99539913
return tools.maybeCallback(callback);
99549914
}
@@ -10994,19 +10954,19 @@ export class AdapterClass extends EventEmitter {
1099410954
}
1099510955
} else if (!this._stopInProgress && this.adapterReady && this.aliases.has(id)) {
1099610956
// If adapter is ready and for this ID exist some alias links
10997-
const alias = this.aliases.get(id);
10957+
const alias = this.aliases.get(id)!;
1099810958
/** Prevent multiple publishes if multiple pattern contain this alias id */
1099910959
const uniqueTargets = new Set<string>();
1100010960

11001-
for (const target of alias!.targets) {
10961+
for (const target of alias.targets) {
1100210962
const targetId = target.id;
1100310963
if (uniqueTargets.has(targetId)) {
1100410964
continue;
1100510965
}
1100610966

1100710967
uniqueTargets.add(targetId);
1100810968

11009-
const source = alias!.source!;
10969+
const source = alias!.source;
1101010970

1101110971
const aState = state
1101210972
? tools.formatAliasValue({
@@ -11193,18 +11153,14 @@ export class AdapterClass extends EventEmitter {
1119311153

1119411154
// if linked ID changed
1119511155
if (newSourceId !== sourceId) {
11196-
this._removeAliasSubscribe(sourceId, targetAlias, async () => {
11197-
try {
11198-
await this._addAliasSubscribe(
11199-
obj as ioBroker.StateObject,
11200-
targetAlias.pattern
11201-
);
11202-
} catch (e) {
11203-
this._logger.error(
11204-
`${this.namespaceLog} Could not add alias subscription: ${e.message}`
11205-
);
11206-
}
11207-
});
11156+
await this._removeAliasSubscribe(sourceId, targetAlias);
11157+
try {
11158+
await this._addAliasSubscribe(obj, targetAlias.pattern);
11159+
} catch (e) {
11160+
this._logger.error(
11161+
`${this.namespaceLog} Could not add alias subscription: ${e.message}`
11162+
);
11163+
}
1120811164
} else {
1120911165
// update attributes
1121011166
targetAlias.min = obj.common.min;
@@ -11215,13 +11171,13 @@ export class AdapterClass extends EventEmitter {
1121511171
} else {
1121611172
// link was deleted
1121711173
// remove from targets array
11218-
this._removeAliasSubscribe(sourceId, targetAlias);
11174+
await this._removeAliasSubscribe(sourceId, targetAlias);
1121911175
}
1122011176
}
1122111177
}
1122211178

1122311179
// it's a new alias, we add it to our subscription
11224-
if (isNewAlias) {
11180+
if (isNewAlias && obj) {
1122511181
for (const aliasPattern of this.aliasPatterns) {
1122611182
// check if it's in our subs range, if so add it
1122711183
const testPattern =
@@ -11234,7 +11190,7 @@ export class AdapterClass extends EventEmitter {
1123411190
(testPattern instanceof RegExp && testPattern.test(id))
1123511191
) {
1123611192
try {
11237-
await this._addAliasSubscribe(obj as ioBroker.StateObject, id);
11193+
await this._addAliasSubscribe(obj, id);
1123811194
} catch (e) {
1123911195
this._logger.warn(
1124011196
`${this.namespaceLog} Could not add alias subscription: ${e.message}`

0 commit comments

Comments
 (0)