Skip to content

Mark and save plugin as disabled if platform fails to initialize #3800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: latest
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bridgeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export interface HomebridgeConfig {
* Unlike the plugins[] config which prevents plugins from being initialised at all, disabled plugins still have their alias loaded, so
* we can match config blocks of disabled plugins and show an appropriate message in the logs.
*/
disabledPlugins?: PluginIdentifier[];
disabledPlugins: PluginIdentifier[];

// This section is used to control the range of ports (inclusive) that separate accessory (like camera or television) should be bind to
ports?: ExternalPortsConfiguration;
Expand Down
51 changes: 39 additions & 12 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ export class Server {
this.printSetupInfo(this.config.bridge.pin);
}

private static saveConfig(config: HomebridgeConfig) {
// Look for the configuration file
const configPath = User.configPath();

fs.writeFileSync(configPath, JSON.stringify(config), { encoding: "utf8", flag: "w" });
}

private static loadConfig(): HomebridgeConfig {
// Look for the configuration file
const configPath = User.configPath();
Expand All @@ -208,6 +215,7 @@ export class Server {
bridge: defaultBridge,
accessories: [],
platforms: [],
disabledPlugins: [],
};
}

Expand Down Expand Up @@ -246,6 +254,7 @@ export class Server {

config.accessories = config.accessories || [];
config.platforms = config.platforms || [];
config.disabledPlugins = config.disabledPlugins || [];

if (!Array.isArray(config.accessories)) {
log.error("Value provided for accessories must be an array[]");
Expand All @@ -257,6 +266,11 @@ export class Server {
config.platforms = [];
}

if (!Array.isArray(config.disabledPlugins)) {
log.error("Value provided for disabledPlugins must be an array[]");
config.disabledPlugins = [];
}

log.info("Loaded config.json with %s accessories and %s platforms.", config.accessories.length, config.platforms.length);

if (config.bridge.advertiser) {
Expand Down Expand Up @@ -395,6 +409,7 @@ export class Server {

const platformIdentifier: PlatformName | PlatformIdentifier = platformConfig.platform;
const displayName = platformConfig.name || platformIdentifier;
const logger = Logger.withPrefix(displayName);

let plugin: Plugin;
let constructor: PlatformPluginConstructor;
Expand Down Expand Up @@ -425,7 +440,30 @@ export class Server {
return;
}

const logger = Logger.withPrefix(displayName);
// If a plugin throws an error, don't let it prevent Homebridge from starting up
// Mark it as disabled and move to next plugin
try {
const platform: PlatformPlugin = new constructor(logger, platformConfig, this.api);

if (HomebridgeAPI.isDynamicPlatformPlugin(platform)) {
plugin.assignDynamicPlatform(platformIdentifier, platform);
} else if (HomebridgeAPI.isStaticPlatformPlugin(platform)) { // Plugin 1.0, load accessories
promises.push(this.bridgeService.loadPlatformAccessories(plugin, platform, platformIdentifier, logger));
} else {
// otherwise it's a IndependentPlatformPlugin which doesn't expose any methods at all.
// We just call the constructor and let it be enabled.
}
} catch (error) {
// Mark and save the plugin as disabled. The user will have to manually enable it once they believe the issue is fixed
plugin.disabled = true;
this.config.disabledPlugins.push(plugin.getPluginIdentifier());
Server.saveConfig(this.config);

log.error(`Error instantiating the plugin ${plugin.getPluginIdentifier()}. Marking it as disabled.`);
log.error(error.message);
return;
}

logger("Initializing %s platform...", platformIdentifier);

if (platformConfig._bridge) {
Expand Down Expand Up @@ -458,17 +496,6 @@ export class Server {
childBridge.addConfig(platformConfig);
return;
}

const platform: PlatformPlugin = new constructor(logger, platformConfig, this.api);

if (HomebridgeAPI.isDynamicPlatformPlugin(platform)) {
plugin.assignDynamicPlatform(platformIdentifier, platform);
} else if (HomebridgeAPI.isStaticPlatformPlugin(platform)) { // Plugin 1.0, load accessories
promises.push(this.bridgeService.loadPlatformAccessories(plugin, platform, platformIdentifier, logger));
} else {
// otherwise it's a IndependentPlatformPlugin which doesn't expose any methods at all.
// We just call the constructor and let it be enabled.
}
});

return promises;
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy