Skip to content

Commit

Permalink
fix: Enforce no floating promises (#22880)
Browse files Browse the repository at this point in the history
* Enforce no floating promises.

* forEach => for/of. Fix tests.
  • Loading branch information
Nerivec authored Jun 4, 2024
1 parent dbf0a33 commit 2b8eaa1
Show file tree
Hide file tree
Showing 22 changed files with 231 additions and 231 deletions.
6 changes: 4 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ module.exports = {
'rules': {
'require-jsdoc': 'off',
'indent': ['error', 4],
'max-len': ['error', {'code': 120}],
'max-len': ['error', {'code': 150}],
'no-prototype-builtins': 'off',
'linebreak-style': ['error', (process.platform === 'win32' ? 'windows' : 'unix')], // https://stackoverflow.com/q/39114446/2771889
'@typescript-eslint/no-floating-promises': 'error',
},
'plugins': [
'jest',
Expand All @@ -38,9 +39,10 @@ module.exports = {
'@typescript-eslint/semi': ['error'],
'array-bracket-spacing': ['error', 'never'],
'indent': ['error', 4],
'max-len': ['error', {'code': 120}],
'max-len': ['error', {'code': 150}],
'no-return-await': 'error',
'object-curly-spacing': ['error', 'never'],
'@typescript-eslint/no-floating-promises': 'error',
},
}],
};
14 changes: 1 addition & 13 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,14 @@ tsconfig.tsbuildinfo
# dotenv environment variables file
.env

# data
data/database.db
data/config.json
data/log*.txt
data/state.json
data/log
data-backup/
data/coordinator_backup.json
data/.storage
data/database.db.backup
data/extension

# MacOS indexing file
.DS_Store

# IDE specific folders
.idea

# Ignore config
data/*.yaml
data/*
!data/configuration.example.yaml

# commit-user-lookup.json
Expand Down
4 changes: 2 additions & 2 deletions lib/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class Controller {
settings.set(['advanced', 'legacy_api'], false);
settings.set(['advanced', 'legacy_availability_payload'], false);
settings.set(['device_options', 'legacy'], false);
this.enableDisableExtension(false, 'BridgeLegacy');
await this.enableDisableExtension(false, 'BridgeLegacy');
}

// Log zigbee clients on startup
Expand Down Expand Up @@ -164,7 +164,7 @@ export class Controller {
if (settings.get().advanced.cache_state_send_on_startup && settings.get().advanced.cache_state) {
for (const entity of [...devices, ...this.zigbee.groups()]) {
if (this.state.exists(entity)) {
this.publishEntityState(entity, this.state.get(entity), 'publishCached');
await this.publishEntityState(entity, this.state.get(entity), 'publishCached');
}
}
}
Expand Down
32 changes: 16 additions & 16 deletions lib/extension/availability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export default class Availability extends Extension {
}
}

private addToPingQueue(device: Device): void {
private async addToPingQueue(device: Device): Promise<void> {
this.pingQueue.push(device);
this.pingQueueExecuteNext();
await this.pingQueueExecuteNext();
}

private removeFromPingQueue(device: Device): void {
Expand Down Expand Up @@ -99,25 +99,25 @@ export default class Availability extends Extension {
return;
}

this.publishAvailability(device, !pingedSuccessfully);
await this.publishAvailability(device, !pingedSuccessfully);
this.resetTimer(device);
this.removeFromPingQueue(device);

// Sleep 2 seconds before executing next ping
await utils.sleep(2);
this.pingQueueExecuting = false;
this.pingQueueExecuteNext();
await this.pingQueueExecuteNext();
}

override async start(): Promise<void> {
if (this.stopped) {
throw new Error('This extension cannot be restarted.');
}

this.eventBus.onEntityRenamed(this, (data) => {
this.eventBus.onEntityRenamed(this, async (data) => {
if (utils.isAvailabilityEnabledForEntity(data.entity, settings.get())) {
this.mqtt.publish(`${data.from}/availability`, null, {retain: true, qos: 1});
this.publishAvailability(data.entity, false, true);
await this.mqtt.publish(`${data.from}/availability`, null, {retain: true, qos: 1});
await this.publishAvailability(data.entity, false, true);
}
});

Expand All @@ -127,29 +127,29 @@ export default class Availability extends Extension {
this.eventBus.onLastSeenChanged(this, this.onLastSeenChanged);
this.eventBus.onPublishAvailability(this, this.publishAvailabilityForAllEntities);
this.eventBus.onGroupMembersChanged(this, (data) => this.publishAvailability(data.group, false));
this.publishAvailabilityForAllEntities();
await this.publishAvailabilityForAllEntities();
}

@bind private publishAvailabilityForAllEntities(): void {
@bind private async publishAvailabilityForAllEntities(): Promise<void> {
for (const entity of [...this.zigbee.devices(false), ...this.zigbee.groups()]) {
if (utils.isAvailabilityEnabledForEntity(entity, settings.get())) {
// Publish initial availability
this.publishAvailability(entity, true, false, true);
await this.publishAvailability(entity, true, false, true);

if (entity.isDevice()) {
this.resetTimer(entity);

// If an active device is initially unavailable, ping it.
if (this.isActiveDevice(entity) && !this.isAvailable(entity)) {
this.addToPingQueue(entity);
await this.addToPingQueue(entity);
}
}
}
}
}

private publishAvailability(entity: Device | Group, logLastSeen: boolean,
forcePublish=false, skipGroups=false): void {
private async publishAvailability(entity: Device | Group, logLastSeen: boolean,
forcePublish=false, skipGroups=false): Promise<void> {
if (logLastSeen && entity.isDevice()) {
const ago = Date.now() - entity.zh.lastSeen;
if (this.isActiveDevice(entity)) {
Expand All @@ -175,7 +175,7 @@ export default class Availability extends Extension {
const topic = `${entity.name}/availability`;
const payload = utils.availabilityPayload(available ? 'online' : 'offline', settings.get());
this.availabilityCache[entity.ID] = available;
this.mqtt.publish(topic, payload, {retain: true, qos: 1});
await this.mqtt.publish(topic, payload, {retain: true, qos: 1});

if (!skipGroups && entity.isDevice()) {
this.zigbee.groups().filter((g) => g.hasMember(entity))
Expand All @@ -184,12 +184,12 @@ export default class Availability extends Extension {
}
}

@bind private onLastSeenChanged(data: eventdata.LastSeenChanged): void {
@bind private async onLastSeenChanged(data: eventdata.LastSeenChanged): Promise<void> {
if (utils.isAvailabilityEnabledForEntity(data.device, settings.get())) {
// Remove from ping queue, not necessary anymore since we know the device is online.
this.removeFromPingQueue(data.device);
this.resetTimer(data.device);
this.publishAvailability(data.device, false);
await this.publishAvailability(data.device, false);
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/extension/bind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export default class Bind extends Extension {

/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
await this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}`,
message: {from: source.name, to: target.name, cluster}}),
Expand All @@ -300,7 +300,7 @@ export default class Bind extends Extension {

/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
await this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}_failed`,
message: {from: source.name, to: target.name, cluster}}),
Expand All @@ -316,7 +316,7 @@ export default class Bind extends Extension {

/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
await this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}_failed`, message: {from: source.name, to: target.name}}),
);
Expand Down
72 changes: 36 additions & 36 deletions lib/extension/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default class Bridge extends Extension {

if (payload !== this.lastBridgeLoggingPayload) {
this.lastBridgeLoggingPayload = payload;
this.mqtt.publish(`bridge/logging`, payload, {}, baseTopic, true);
void this.mqtt.publish(`bridge/logging`, payload, {}, baseTopic, true);
}
};

Expand Down Expand Up @@ -111,38 +111,38 @@ export default class Bridge extends Extension {
this.publishInfo() &&
this.publishDefinitions());
this.eventBus.onPermitJoinChanged(this, () => !this.zigbee.isStopping() && this.publishInfo());
this.eventBus.onScenesChanged(this, () => {
this.publishDevices();
this.publishGroups();
this.eventBus.onScenesChanged(this, async () => {
await this.publishDevices();
await this.publishGroups();
});

// Zigbee events
const publishEvent = (type: string, data: KeyValue): Promise<void> =>
const publishEvent = async (type: string, data: KeyValue): Promise<void> =>
this.mqtt.publish('bridge/event', stringify({type, data}), {retain: false, qos: 0});
this.eventBus.onDeviceJoined(this, (data) => {
this.eventBus.onDeviceJoined(this, async (data) => {
this.lastJoinedDeviceIeeeAddr = data.device.ieeeAddr;
this.publishDevices();
publishEvent('device_joined', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
await this.publishDevices();
await publishEvent('device_joined', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
});
this.eventBus.onDeviceLeave(this, (data) => {
this.publishDevices();
this.publishDefinitions();
publishEvent('device_leave', {ieee_address: data.ieeeAddr, friendly_name: data.name});
this.eventBus.onDeviceLeave(this, async (data) => {
await this.publishDevices();
await this.publishDefinitions();
await publishEvent('device_leave', {ieee_address: data.ieeeAddr, friendly_name: data.name});
});
this.eventBus.onDeviceNetworkAddressChanged(this, () => this.publishDevices());
this.eventBus.onDeviceInterview(this, (data) => {
this.publishDevices();
this.eventBus.onDeviceInterview(this, async (data) => {
await this.publishDevices();
const payload: KeyValue =
{friendly_name: data.device.name, status: data.status, ieee_address: data.device.ieeeAddr};
if (data.status === 'successful') {
payload.supported = data.device.isSupported;
payload.definition = this.getDefinitionPayload(data.device);
}
publishEvent('device_interview', payload);
await publishEvent('device_interview', payload);
});
this.eventBus.onDeviceAnnounce(this, (data) => {
this.publishDevices();
publishEvent('device_announce', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
this.eventBus.onDeviceAnnounce(this, async (data) => {
await this.publishDevices();
await publishEvent('device_announce', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
});

await this.publishInfo();
Expand All @@ -154,7 +154,7 @@ export default class Bridge extends Extension {
}

override async stop(): Promise<void> {
super.stop();
await super.stop();
logger.removeTransport(this.logTransport);
}

Expand Down Expand Up @@ -219,7 +219,7 @@ export default class Bridge extends Extension {
}

logger.info('Successfully changed options');
this.publishInfo();
await this.publishInfo();
return utils.getResponse(message, {restart_required: this.restartRequired}, null);
}

Expand Down Expand Up @@ -252,7 +252,7 @@ export default class Bridge extends Extension {
const ID = typeof message === 'object' && message.hasOwnProperty('id') ? message.id : null;
const group = settings.addGroup(friendlyName, ID);
this.zigbee.createGroup(group.ID);
this.publishGroups();
await this.publishGroups();
return utils.getResponse(message, {friendly_name: group.friendly_name, id: group.ID}, null);
}

Expand Down Expand Up @@ -336,7 +336,7 @@ export default class Bridge extends Extension {
}

settings.set(['advanced', 'last_seen'], value);
this.publishInfo();
await this.publishInfo();
return utils.getResponse(message, {value}, null);
}

Expand All @@ -350,7 +350,7 @@ export default class Bridge extends Extension {

await this.enableDisableExtension(value, 'HomeAssistant');
settings.set(['homeassistant'], value);
this.publishInfo();
await this.publishInfo();
return utils.getResponse(message, {value}, null);
}

Expand All @@ -363,7 +363,7 @@ export default class Bridge extends Extension {
}

settings.set(['advanced', 'elapsed'], value);
this.publishInfo();
await this.publishInfo();
return utils.getResponse(message, {value}, null);
}

Expand All @@ -375,7 +375,7 @@ export default class Bridge extends Extension {
}

logger.setLevel(value);
this.publishInfo();
await this.publishInfo();
return utils.getResponse(message, {value}, null);
}

Expand Down Expand Up @@ -490,7 +490,7 @@ export default class Bridge extends Extension {
maximumReportInterval: message.maximum_report_interval, reportableChange: message.reportable_change,
}], message.options);

this.publishDevices();
await this.publishDevices();

logger.info(`Configured reporting for '${message.id}', '${message.cluster}.${message.attribute}'`);

Expand Down Expand Up @@ -556,19 +556,19 @@ export default class Bridge extends Extension {
settings.changeFriendlyName(from, to);

// Clear retained messages
this.mqtt.publish(oldFriendlyName, '', {retain: true});
await this.mqtt.publish(oldFriendlyName, '', {retain: true});

this.eventBus.emitEntityRenamed({entity: entity, homeAssisantRename, from: oldFriendlyName, to});

if (entity instanceof Device) {
this.publishDevices();
await this.publishDevices();
} else {
this.publishGroups();
this.publishInfo();
await this.publishGroups();
await this.publishInfo();
}

// Republish entity state
this.publishEntityState(entity, {});
await this.publishEntityState(entity, {});

return utils.getResponse(
message,
Expand Down Expand Up @@ -635,18 +635,18 @@ export default class Bridge extends Extension {
this.state.remove(entityID);

// Clear any retained messages
this.mqtt.publish(friendlyName, '', {retain: true});
await this.mqtt.publish(friendlyName, '', {retain: true});

logger.info(`Successfully removed ${entityType} '${friendlyName}'${blockForceLog}`);

if (entity instanceof Device) {
this.publishGroups();
this.publishDevices();
await this.publishGroups();
await this.publishDevices();
// Refresh Cluster definition
this.publishDefinitions();
await this.publishDefinitions();
return utils.getResponse(message, {id: ID, block, force}, null);
} else {
this.publishGroups();
await this.publishGroups();
return utils.getResponse(message, {id: ID, force: force}, null);
}
} catch (error) {
Expand Down
Loading

0 comments on commit 2b8eaa1

Please sign in to comment.