fix: resolve all TypeScript type errors across codebase for Deno strict mode

Comprehensive type safety improvements across all CLI handlers and daemon:

**Error handling type fixes:**
- Add 'error instanceof Error' checks before accessing error.message throughout
- Fix all error/retryError/stdError/upsError type assertions
- Replace direct error.message with proper type guards

**Switch case improvements:**
- Wrap case block declarations in braces to satisfy deno-lint
- Fix no-case-declarations warnings in CLI command handlers

**Null/undefined safety:**
- Add checks for config.snmp and config.thresholds before access
- Fix IUpsStatus lastStatusChange to handle undefined with default value
- Add proper null checks in legacy configuration paths

**Type annotations:**
- Add explicit type annotations to lambda parameters (groupId, updateAvailable, etc.)
- Add TUpsModel type cast for 'cyberpower' default
- Import and use INupstConfig type where needed

**Parameter type fixes:**
- Fix implicit 'any' type errors in array callbacks
- Add type annotations to filter/find/map parameters

Files modified:
- ts/cli.ts: config.snmp/thresholds null checks, unused error variable fixes
- ts/cli/group-handler.ts: 4 error.message fixes + 2 parameter type annotations
- ts/cli/service-handler.ts: 3 error.message fixes
- ts/cli/ups-handler.ts: 5 error.message fixes + config checks + TUpsModel import
- ts/daemon.ts: 8 error.message fixes + IUpsStatus lastStatusChange fix + updateAvailable type
- ts/nupst.ts: 1 error.message fix
- ts/systemd.ts: 5 error.message fixes + parameter type annotation

All tests passing (3/3 SNMP tests + 10/10 logger tests)
Type check: ✓ No errors
This commit is contained in:
2025-10-18 21:07:57 +00:00
parent 9ccbbbdc37
commit c2d39cc19a
7 changed files with 112 additions and 86 deletions

View File

@@ -115,13 +115,14 @@ export class NupstCli {
case 'add': case 'add':
await upsHandler.add(); await upsHandler.add();
break; break;
case 'edit': case 'edit': {
const upsId = subcommandArgs[0]; const upsId = subcommandArgs[0];
await upsHandler.edit(upsId); await upsHandler.edit(upsId);
break; break;
}
case 'remove': case 'remove':
case 'rm': // Alias case 'rm': // Alias
case 'delete': // Backward compatibility case 'delete': { // Backward compatibility
const upsIdToRemove = subcommandArgs[0]; const upsIdToRemove = subcommandArgs[0];
if (!upsIdToRemove) { if (!upsIdToRemove) {
logger.error('UPS ID is required for remove command'); logger.error('UPS ID is required for remove command');
@@ -130,6 +131,7 @@ export class NupstCli {
} }
await upsHandler.remove(upsIdToRemove); await upsHandler.remove(upsIdToRemove);
break; break;
}
case 'list': case 'list':
case 'ls': // Alias case 'ls': // Alias
await upsHandler.list(); await upsHandler.list();
@@ -153,7 +155,7 @@ export class NupstCli {
case 'add': case 'add':
await groupHandler.add(); await groupHandler.add();
break; break;
case 'edit': case 'edit': {
const groupId = subcommandArgs[0]; const groupId = subcommandArgs[0];
if (!groupId) { if (!groupId) {
logger.error('Group ID is required for edit command'); logger.error('Group ID is required for edit command');
@@ -162,9 +164,10 @@ export class NupstCli {
} }
await groupHandler.edit(groupId); await groupHandler.edit(groupId);
break; break;
}
case 'remove': case 'remove':
case 'rm': // Alias case 'rm': // Alias
case 'delete': // Backward compatibility case 'delete': { // Backward compatibility
const groupIdToRemove = subcommandArgs[0]; const groupIdToRemove = subcommandArgs[0];
if (!groupIdToRemove) { if (!groupIdToRemove) {
logger.error('Group ID is required for remove command'); logger.error('Group ID is required for remove command');
@@ -173,6 +176,7 @@ export class NupstCli {
} }
await groupHandler.remove(groupIdToRemove); await groupHandler.remove(groupIdToRemove);
break; break;
}
case 'list': case 'list':
case 'ls': // Alias case 'ls': // Alias
await groupHandler.list(); await groupHandler.list();
@@ -291,7 +295,7 @@ export class NupstCli {
// Try to load configuration // Try to load configuration
try { try {
await this.nupst.getDaemon().loadConfig(); await this.nupst.getDaemon().loadConfig();
} catch (error) { } catch (_error) {
const errorBoxWidth = 45; const errorBoxWidth = 45;
logger.logBoxTitle('Configuration Error', errorBoxWidth); logger.logBoxTitle('Configuration Error', errorBoxWidth);
logger.logBoxLine('No configuration found.'); logger.logBoxLine('No configuration found.');
@@ -351,6 +355,9 @@ export class NupstCli {
} }
} else { } else {
// Legacy single UPS configuration // Legacy single UPS configuration
if (!config.snmp) {
logger.logBoxLine('Error: Legacy configuration missing SNMP settings');
} else {
// SNMP Settings // SNMP Settings
logger.logBoxLine('SNMP Settings:'); logger.logBoxLine('SNMP Settings:');
logger.logBoxLine(` Host: ${config.snmp.host}`); logger.logBoxLine(` Host: ${config.snmp.host}`);
@@ -389,11 +396,16 @@ export class NupstCli {
); );
logger.logBoxLine(` Battery Runtime: ${config.snmp.customOIDs.BATTERY_RUNTIME || 'Not set'}`); logger.logBoxLine(` Battery Runtime: ${config.snmp.customOIDs.BATTERY_RUNTIME || 'Not set'}`);
} }
}
// Thresholds // Thresholds
if (!config.thresholds) {
logger.logBoxLine('Error: Legacy configuration missing threshold settings');
} else {
logger.logBoxLine('Thresholds:'); logger.logBoxLine('Thresholds:');
logger.logBoxLine(` Battery: ${config.thresholds.battery}%`); logger.logBoxLine(` Battery: ${config.thresholds.battery}%`);
logger.logBoxLine(` Runtime: ${config.thresholds.runtime} minutes`); logger.logBoxLine(` Runtime: ${config.thresholds.runtime} minutes`);
}
logger.logBoxLine(`Check Interval: ${config.checkInterval / 1000} seconds`); logger.logBoxLine(`Check Interval: ${config.checkInterval / 1000} seconds`);
// Configuration file location // Configuration file location
@@ -419,11 +431,11 @@ export class NupstCli {
logger.logBoxLine(`Service Active: ${isActive ? 'Yes' : 'No'}`); logger.logBoxLine(`Service Active: ${isActive ? 'Yes' : 'No'}`);
logger.logBoxLine(`Service Enabled: ${isEnabled ? 'Yes' : 'No'}`); logger.logBoxLine(`Service Enabled: ${isEnabled ? 'Yes' : 'No'}`);
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (_error) {
// Ignore errors checking service status // Ignore errors checking service status
} }
} catch (error) { } catch (error) {
logger.error(`Failed to display configuration: ${error.message}`); logger.error(`Failed to display configuration: ${error instanceof Error ? error.message : String(error)}`);
} }
} }

View File

@@ -78,7 +78,7 @@ export class GroupHandler {
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
logger.error(`Failed to list UPS groups: ${error.message}`); logger.error(`Failed to list UPS groups: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -187,7 +187,7 @@ export class GroupHandler {
rl.close(); rl.close();
} }
} catch (error) { } catch (error) {
logger.error(`Add group error: ${error.message}`); logger.error(`Add group error: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -298,7 +298,7 @@ export class GroupHandler {
rl.close(); rl.close();
} }
} catch (error) { } catch (error) {
logger.error(`Edit group error: ${error.message}`); logger.error(`Edit group error: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -375,7 +375,7 @@ export class GroupHandler {
// Check if service is running and restart it if needed // Check if service is running and restart it if needed
this.nupst.getUpsHandler().restartServiceIfRunning(); this.nupst.getUpsHandler().restartServiceIfRunning();
} catch (error) { } catch (error) {
logger.error(`Failed to delete group: ${error.message}`); logger.error(`Failed to delete group: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -485,7 +485,7 @@ export class GroupHandler {
return; return;
} }
const group = config.groups.find(g => g.id === groupId); const group = config.groups.find((g: { id: string }) => g.id === groupId);
if (!group) { if (!group) {
logger.error(`Group with ID "${groupId}" not found.`); logger.error(`Group with ID "${groupId}" not found.`);
return; return;
@@ -493,7 +493,7 @@ export class GroupHandler {
// Show current assignments // Show current assignments
logger.log(`\nUPS devices in group "${group.name}" (${group.id}):`); logger.log(`\nUPS devices in group "${group.name}" (${group.id}):`);
const upsInGroup = config.upsDevices.filter(ups => ups.groups && ups.groups.includes(groupId)); const upsInGroup = config.upsDevices.filter((ups: { groups?: string[] }) => ups.groups && ups.groups.includes(groupId));
if (upsInGroup.length === 0) { if (upsInGroup.length === 0) {
logger.log('- None'); logger.log('- None');
} else { } else {

View File

@@ -201,12 +201,12 @@ export class ServiceHandler {
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
logger.logBoxLine('Error during update process:'); logger.logBoxLine('Error during update process:');
logger.logBoxLine(`${error.message}`); logger.logBoxLine(`${error instanceof Error ? error.message : String(error)}`);
logger.logBoxEnd(); logger.logBoxEnd();
process.exit(1); process.exit(1);
} }
} catch (error) { } catch (error) {
logger.error(`Update failed: ${error.message}`); logger.error(`Update failed: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1); process.exit(1);
} }
} }
@@ -300,7 +300,7 @@ export class ServiceHandler {
stdio: 'inherit', // Show output in the terminal stdio: 'inherit', // Show output in the terminal
}); });
} catch (error) { } catch (error) {
console.error(`Uninstall failed: ${error.message}`); console.error(`Uninstall failed: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1); process.exit(1);
} }
} }

View File

@@ -2,6 +2,8 @@ import { execSync } from "node:child_process";
import { Nupst } from '../nupst.ts'; import { Nupst } from '../nupst.ts';
import { logger } from '../logger.ts'; import { logger } from '../logger.ts';
import * as helpers from '../helpers/index.ts'; import * as helpers from '../helpers/index.ts';
import type { TUpsModel } from '../snmp/types.ts';
import type { INupstConfig } from '../daemon.ts';
/** /**
* Class for handling UPS-related CLI commands * Class for handling UPS-related CLI commands
@@ -46,7 +48,7 @@ export class UpsHandler {
rl.close(); rl.close();
} }
} catch (error) { } catch (error) {
logger.error(`Add UPS error: ${error.message}`); logger.error(`Add UPS error: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -105,7 +107,7 @@ export class UpsHandler {
community: 'public', community: 'public',
version: 1, version: 1,
timeout: 5000, timeout: 5000,
upsModel: 'cyberpower' upsModel: 'cyberpower' as TUpsModel
}, },
thresholds: { thresholds: {
battery: 60, battery: 60,
@@ -135,7 +137,7 @@ export class UpsHandler {
config.upsDevices.push(newUps); config.upsDevices.push(newUps);
// Save the configuration // Save the configuration
await this.nupst.getDaemon().saveConfig(config); await this.nupst.getDaemon().saveConfig(config as INupstConfig);
this.displayUpsConfigSummary(newUps); this.displayUpsConfigSummary(newUps);
@@ -177,7 +179,7 @@ export class UpsHandler {
rl.close(); rl.close();
} }
} catch (error) { } catch (error) {
logger.error(`Edit UPS error: ${error.message}`); logger.error(`Edit UPS error: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -212,6 +214,10 @@ export class UpsHandler {
// Convert old format to new format if needed // Convert old format to new format if needed
if (!config.upsDevices) { if (!config.upsDevices) {
// Initialize with the current config as the first UPS // Initialize with the current config as the first UPS
if (!config.snmp || !config.thresholds) {
logger.error('Legacy configuration is missing required SNMP or threshold settings');
return;
}
config.upsDevices = [{ config.upsDevices = [{
id: 'default', id: 'default',
name: 'Default UPS', name: 'Default UPS',
@@ -348,7 +354,7 @@ export class UpsHandler {
// Check if service is running and restart it if needed // Check if service is running and restart it if needed
await this.restartServiceIfRunning(); await this.restartServiceIfRunning();
} catch (error) { } catch (error) {
logger.error(`Failed to delete UPS: ${error.message}`); logger.error(`Failed to delete UPS: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -378,6 +384,12 @@ export class UpsHandler {
const boxWidth = 45; const boxWidth = 45;
logger.logBoxTitle('UPS Devices', boxWidth); logger.logBoxTitle('UPS Devices', boxWidth);
logger.logBoxLine('Legacy single-UPS configuration detected.'); logger.logBoxLine('Legacy single-UPS configuration detected.');
if (!config.snmp || !config.thresholds) {
logger.logBoxLine('');
logger.logBoxLine('Error: Configuration missing SNMP or threshold settings');
logger.logBoxEnd();
return;
}
logger.logBoxLine(''); logger.logBoxLine('');
logger.logBoxLine('Default UPS:'); logger.logBoxLine('Default UPS:');
logger.logBoxLine(` Host: ${config.snmp.host}:${config.snmp.port}`); logger.logBoxLine(` Host: ${config.snmp.host}:${config.snmp.port}`);
@@ -416,7 +428,7 @@ export class UpsHandler {
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
logger.error(`Failed to list UPS devices: ${error.message}`); logger.error(`Failed to list UPS devices: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -465,7 +477,7 @@ export class UpsHandler {
await this.testConnection(config); await this.testConnection(config);
} }
} catch (error) { } catch (error) {
logger.error(`Test failed: ${error.message}`); logger.error(`Test failed: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -568,7 +580,7 @@ export class UpsHandler {
} catch (error) { } catch (error) {
const errorBoxWidth = 45; const errorBoxWidth = 45;
logger.logBoxTitle(`Connection Failed: ${upsName}`, errorBoxWidth); logger.logBoxTitle(`Connection Failed: ${upsName}`, errorBoxWidth);
logger.logBoxLine(`Error: ${error.message}`); logger.logBoxLine(`Error: ${error instanceof Error ? error.message : String(error)}`);
logger.logBoxEnd(); logger.logBoxEnd();
logger.log("\nPlease check your settings and run 'nupst edit' to reconfigure this UPS."); logger.log("\nPlease check your settings and run 'nupst edit' to reconfigure this UPS.");
} }
@@ -937,7 +949,7 @@ export class UpsHandler {
const errorBoxWidth = 45; const errorBoxWidth = 45;
logger.log(''); logger.log('');
logger.logBoxTitle('Connection Failed!', errorBoxWidth); logger.logBoxTitle('Connection Failed!', errorBoxWidth);
logger.logBoxLine(`Error: ${error.message}`); logger.logBoxLine(`Error: ${error instanceof Error ? error.message : String(error)}`);
logger.logBoxEnd(); logger.logBoxEnd();
logger.log('\nPlease check your settings and try again.'); logger.log('\nPlease check your settings and try again.');
} }
@@ -972,7 +984,7 @@ export class UpsHandler {
logger.logBoxLine(' sudo systemctl restart nupst.service'); logger.logBoxLine(' sudo systemctl restart nupst.service');
} }
} catch (error) { } catch (error) {
logger.logBoxLine(`Error restarting service: ${error.message}`); logger.logBoxLine(`Error restarting service: ${error instanceof Error ? error.message : String(error)}`);
logger.logBoxLine('You may need to restart the service manually:'); logger.logBoxLine('You may need to restart the service manually:');
logger.logBoxLine(' sudo systemctl restart nupst.service'); logger.logBoxLine(' sudo systemctl restart nupst.service');
} }

View File

@@ -179,11 +179,11 @@ export class NupstDaemon {
return this.config; return this.config;
} catch (error) { } catch (error) {
if (error.message && error.message.includes('No configuration found')) { if (error instanceof Error && error.message && error.message.includes('No configuration found')) {
throw error; // Re-throw the no configuration error throw error; // Re-throw the no configuration error
} }
this.logConfigError(`Error loading configuration: ${error.message}`); this.logConfigError(`Error loading configuration: ${error instanceof Error ? error.message : String(error)}`);
throw new Error('Failed to load configuration'); throw new Error('Failed to load configuration');
} }
} }
@@ -252,7 +252,7 @@ export class NupstDaemon {
this.snmp.getNupst().logVersionInfo(false); // Don't check for updates immediately on startup this.snmp.getNupst().logVersionInfo(false); // Don't check for updates immediately on startup
// Check for updates in the background // Check for updates in the background
this.snmp.getNupst().checkForUpdates().then(updateAvailable => { this.snmp.getNupst().checkForUpdates().then((updateAvailable: boolean) => {
if (updateAvailable) { if (updateAvailable) {
const updateStatus = this.snmp.getNupst().getUpdateStatus(); const updateStatus = this.snmp.getNupst().getUpdateStatus();
const boxWidth = 45; const boxWidth = 45;
@@ -272,7 +272,7 @@ export class NupstDaemon {
await this.monitor(); await this.monitor();
} catch (error) { } catch (error) {
this.isRunning = false; this.isRunning = false;
logger.error(`Daemon failed to start: ${error.message}`); logger.error(`Daemon failed to start: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1); // Exit with error process.exit(1); // Exit with error
} }
} }
@@ -373,7 +373,7 @@ export class NupstDaemon {
// Wait before next check // Wait before next check
await this.sleep(this.config.checkInterval); await this.sleep(this.config.checkInterval);
} catch (error) { } catch (error) {
logger.error(`Error during UPS monitoring: ${error.message}`); logger.error(`Error during UPS monitoring: ${error instanceof Error ? error.message : String(error)}`);
await this.sleep(this.config.checkInterval); await this.sleep(this.config.checkInterval);
} }
} }
@@ -409,16 +409,18 @@ export class NupstDaemon {
const currentStatus = this.upsStatus.get(ups.id); const currentStatus = this.upsStatus.get(ups.id);
// Update status with new values // Update status with new values
const updatedStatus = { const updatedStatus: IUpsStatus = {
...currentStatus, id: ups.id,
name: ups.name,
powerStatus: status.powerStatus, powerStatus: status.powerStatus,
batteryCapacity: status.batteryCapacity, batteryCapacity: status.batteryCapacity,
batteryRuntime: status.batteryRuntime, batteryRuntime: status.batteryRuntime,
lastCheckTime: currentTime lastCheckTime: currentTime,
lastStatusChange: currentStatus?.lastStatusChange || currentTime
}; };
// Check if power status changed // Check if power status changed
if (currentStatus.powerStatus !== status.powerStatus) { if (currentStatus && currentStatus.powerStatus !== status.powerStatus) {
logger.logBoxTitle(`Power Status Change: ${ups.name}`, 50); logger.logBoxTitle(`Power Status Change: ${ups.name}`, 50);
logger.logBoxLine(`Status changed: ${currentStatus.powerStatus}${status.powerStatus}`); logger.logBoxLine(`Status changed: ${currentStatus.powerStatus}${status.powerStatus}`);
logger.logBoxEnd(); logger.logBoxEnd();
@@ -429,7 +431,7 @@ export class NupstDaemon {
// Update the status in the map // Update the status in the map
this.upsStatus.set(ups.id, updatedStatus); this.upsStatus.set(ups.id, updatedStatus);
} catch (error) { } catch (error) {
logger.error(`Error checking UPS ${ups.name} (${ups.id}): ${error.message}`); logger.error(`Error checking UPS ${ups.name} (${ups.id}): ${error instanceof Error ? error.message : String(error)}`);
} }
} }
} }
@@ -631,7 +633,7 @@ export class NupstDaemon {
}); });
logger.log(`Shutdown initiated: ${stdout}`); logger.log(`Shutdown initiated: ${stdout}`);
} catch (e) { } catch (e) {
throw new Error(`Shutdown command not found: ${e.message}`); throw new Error(`Shutdown command not found: ${e instanceof Error ? e.message : String(e)}`);
} }
} }
@@ -725,14 +727,14 @@ export class NupstDaemon {
return; return;
} }
} catch (upsError) { } catch (upsError) {
logger.error(`Error checking UPS ${ups.name} during shutdown: ${upsError.message}`); logger.error(`Error checking UPS ${ups.name} during shutdown: ${upsError instanceof Error ? upsError.message : String(upsError)}`);
} }
} }
// Wait before checking again // Wait before checking again
await this.sleep(CHECK_INTERVAL); await this.sleep(CHECK_INTERVAL);
} catch (error) { } catch (error) {
logger.error(`Error monitoring UPS during shutdown: ${error.message}`); logger.error(`Error monitoring UPS during shutdown: ${error instanceof Error ? error.message : String(error)}`);
await this.sleep(CHECK_INTERVAL); await this.sleep(CHECK_INTERVAL);
} }
} }

View File

@@ -103,7 +103,7 @@ export class Nupst {
return this.updateAvailable; return this.updateAvailable;
} catch (error) { } catch (error) {
logger.error(`Error checking for updates: ${error.message}`); logger.error(`Error checking for updates: ${error instanceof Error ? error.message : String(error)}`);
return false; return false;
} }
} }

View File

@@ -81,7 +81,7 @@ WantedBy=multi-user.target
logger.logBoxLine('Service enabled to start on boot'); logger.logBoxLine('Service enabled to start on boot');
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
if (error.message === 'Configuration not found') { if (error instanceof Error && error.message === 'Configuration not found') {
// Just rethrow the error as the message has already been displayed // Just rethrow the error as the message has already been displayed
throw error; throw error;
} }
@@ -105,7 +105,7 @@ WantedBy=multi-user.target
logger.logBoxLine('NUPST service started successfully'); logger.logBoxLine('NUPST service started successfully');
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
if (error.message === 'Configuration not found') { if (error instanceof Error && error.message === 'Configuration not found') {
// Exit with error code since configuration is required // Exit with error code since configuration is required
process.exit(1); process.exit(1);
} }
@@ -157,7 +157,7 @@ WantedBy=multi-user.target
await this.displayServiceStatus(); await this.displayServiceStatus();
await this.displayAllUpsStatus(); await this.displayAllUpsStatus();
} catch (error) { } catch (error) {
logger.error(`Failed to get status: ${error.message}`); logger.error(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`);
} }
} }
@@ -219,7 +219,7 @@ WantedBy=multi-user.target
} catch (error) { } catch (error) {
const boxWidth = 45; const boxWidth = 45;
logger.logBoxTitle('UPS Status', boxWidth); logger.logBoxTitle('UPS Status', boxWidth);
logger.logBoxLine(`Failed to retrieve UPS status: ${error.message}`); logger.logBoxLine(`Failed to retrieve UPS status: ${error instanceof Error ? error.message : String(error)}`);
logger.logBoxEnd(); logger.logBoxEnd();
} }
} }
@@ -239,8 +239,8 @@ WantedBy=multi-user.target
if (ups.groups && ups.groups.length > 0) { if (ups.groups && ups.groups.length > 0) {
// Get group names if available // Get group names if available
const config = this.daemon.getConfig(); const config = this.daemon.getConfig();
const groupNames = ups.groups.map(groupId => { const groupNames = ups.groups.map((groupId: string) => {
const group = config.groups?.find(g => g.id === groupId); const group = config.groups?.find((g: { id: string }) => g.id === groupId);
return group ? group.name : groupId; return group ? group.name : groupId;
}); });
logger.logBoxLine(`Groups: ${groupNames.join(', ')}`); logger.logBoxLine(`Groups: ${groupNames.join(', ')}`);
@@ -275,7 +275,7 @@ WantedBy=multi-user.target
logger.logBoxEnd(); logger.logBoxEnd();
} catch (error) { } catch (error) {
logger.logBoxTitle(`UPS Status: ${ups.name}`, boxWidth); logger.logBoxTitle(`UPS Status: ${ups.name}`, boxWidth);
logger.logBoxLine(`Failed to retrieve UPS status: ${error.message}`); logger.logBoxLine(`Failed to retrieve UPS status: ${error instanceof Error ? error.message : String(error)}`);
logger.logBoxEnd(); logger.logBoxEnd();
} }
} }