mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-07-19 01:56:29 +00:00
fix: Don't crash on startup when external converters fails to load https://github.com/Koenkk/zigbee2mqtt/issues/20010
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import * as zhc from 'zigbee-herdsman-converters';
|
||||
import * as settings from '../util/settings';
|
||||
import utils from '../util/utils';
|
||||
import {loadExternalConverter} from '../util/utils';
|
||||
import Extension from './extension';
|
||||
import logger from '../util/logger';
|
||||
|
||||
export default class ExternalConverters extends Extension {
|
||||
constructor(zigbee: Zigbee, mqtt: MQTT, state: State, publishEntityState: PublishEntityState,
|
||||
@@ -9,10 +10,23 @@ export default class ExternalConverters extends Extension {
|
||||
restartCallback: () => void, addExtension: (extension: Extension) => Promise<void>) {
|
||||
super(zigbee, mqtt, state, publishEntityState, eventBus, enableDisableExtension, restartCallback, addExtension);
|
||||
|
||||
for (const definition of utils.getExternalConvertersDefinitions(settings.get())) {
|
||||
const toAdd = {...definition};
|
||||
delete toAdd['homeassistant'];
|
||||
zhc.addDefinition(toAdd);
|
||||
for (const file of settings.get().external_converters) {
|
||||
try {
|
||||
for (const definition of loadExternalConverter(file)) {
|
||||
const toAdd = {...definition};
|
||||
delete toAdd['homeassistant'];
|
||||
zhc.addDefinition(toAdd);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load external converter file '${file}' (${error.message})`);
|
||||
logger.error(
|
||||
`Probably there is a syntax error in the file or the external converter is not ` +
|
||||
`compatible with the current Zigbee2MQTT version`);
|
||||
logger.error(
|
||||
`Note that external converters are not meant for long term usage, it's meant for local ` +
|
||||
`testing after which a pull request should be created to add out-of-the-box support for the device`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-17
@@ -162,25 +162,21 @@ function loadModuleFromFile(modulePath: string): unknown {
|
||||
return loadModuleFromText(moduleCode);
|
||||
}
|
||||
|
||||
function* getExternalConvertersDefinitions(settings: Settings): Generator<ExternalDefinition> {
|
||||
const externalConverters = settings.external_converters;
|
||||
export function* loadExternalConverter(moduleName: string): Generator<ExternalDefinition> {
|
||||
let converter;
|
||||
|
||||
for (const moduleName of externalConverters) {
|
||||
let converter;
|
||||
if (moduleName.endsWith('.js')) {
|
||||
converter = loadModuleFromFile(data.joinPath(moduleName));
|
||||
} else {
|
||||
converter = require(moduleName);
|
||||
}
|
||||
|
||||
if (moduleName.endsWith('.js')) {
|
||||
converter = loadModuleFromFile(data.joinPath(moduleName));
|
||||
} else {
|
||||
converter = require(moduleName);
|
||||
}
|
||||
|
||||
if (Array.isArray(converter)) {
|
||||
for (const item of converter) {
|
||||
yield item;
|
||||
}
|
||||
} else {
|
||||
yield converter;
|
||||
if (Array.isArray(converter)) {
|
||||
for (const item of converter) {
|
||||
yield item;
|
||||
}
|
||||
} else {
|
||||
yield converter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,7 +435,7 @@ function getScenes(entity: zh.Endpoint | zh.Group): Scene[] {
|
||||
export default {
|
||||
endpointNames, capitalize, getZigbee2MQTTVersion, getDependencyVersion, formatDate, objectHasProperties,
|
||||
equalsPartial, getObjectProperty, getResponse, parseJSON, loadModuleFromText, loadModuleFromFile,
|
||||
getExternalConvertersDefinitions, removeNullPropertiesFromObject, toNetworkAddressHex, toSnakeCase,
|
||||
removeNullPropertiesFromObject, toNetworkAddressHex, toSnakeCase,
|
||||
parseEntityID, isEndpoint, isZHGroup, hours, minutes, seconds, validateFriendlyName, sleep,
|
||||
sanitizeImageParameter, isAvailabilityEnabledForEntity, publishLastSeen, availabilityPayload,
|
||||
getAllFiles, filterProperties, flatten, arrayUnique, clone, computeSettingsToChange, getScenes,
|
||||
|
||||
@@ -134,4 +134,12 @@ describe('Loads external converters', () => {
|
||||
mock: 2
|
||||
});
|
||||
});
|
||||
|
||||
it('Loads external converters with error', async () => {
|
||||
fs.copyFileSync(path.join(__dirname, 'assets', 'mock-external-converter.js'), path.join(data.mockDir, 'mock-external-converter.js'));
|
||||
settings.set(['external_converters'], ['mock-external-converter.js']);
|
||||
zigbeeHerdsmanConverters.addDefinition.mockImplementationOnce(() => {throw new Error('Invalid definition!')});
|
||||
await resetExtension();
|
||||
expect(logger.error).toHaveBeenCalledWith(`Failed to load external converter file 'mock-external-converter.js' (Invalid definition!)`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user