fix(typescript): tighten TypeScript null safety and error handling across backend and ops UI

This commit is contained in:
2026-03-26 07:40:56 +00:00
parent 0195a21f30
commit 44f2a7f0a9
40 changed files with 414 additions and 451 deletions

View File

@@ -215,7 +215,7 @@ export class DcRouter {
public emailServer?: UnifiedEmailServer;
public radiusServer?: RadiusServer;
public storageManager: StorageManager;
public opsServer: OpsServer;
public opsServer!: OpsServer;
public metricsManager?: MetricsManager;
// Cache system (smartdata + LocalTsmDb)
@@ -448,7 +448,7 @@ export class DcRouter {
}
// DNS Server: optional, depends on SmartProxy
if (this.options.dnsNsDomains?.length > 0 && this.options.dnsScopes?.length > 0) {
if (this.options.dnsNsDomains && this.options.dnsNsDomains.length > 0 && this.options.dnsScopes && this.options.dnsScopes.length > 0) {
this.serviceManager.addService(
new plugins.taskbuffer.Service('DnsServer')
.optional()
@@ -787,7 +787,7 @@ export class DcRouter {
eventComms.log(`Attempting DNS-01 via SmartAcme for ${domain}`);
eventComms.setSource('smartacme-dns-01');
const isWildcardDomain = domain.startsWith('*.');
const cert = await this.smartAcme.getCertificateForDomain(domain, {
const cert = await this.smartAcme!.getCertificateForDomain(domain, {
includeWildcard: !isWildcardDomain,
});
if (cert.validUntil) {
@@ -806,10 +806,10 @@ export class DcRouter {
// Success — clear any backoff
await scheduler.clearBackoff(domain);
return result;
} catch (err) {
} catch (err: unknown) {
// Record failure for backoff tracking
await scheduler.recordFailure(domain, err.message);
eventComms.warn(`SmartAcme DNS-01 failed for ${domain}: ${err.message}, falling back to http-01`);
await scheduler.recordFailure(domain, (err as Error).message);
eventComms.warn(`SmartAcme DNS-01 failed for ${domain}: ${(err as Error).message}, falling back to http-01`);
return 'http01';
}
};
@@ -1248,21 +1248,21 @@ export class DcRouter {
// Wire delivery events to MetricsManager and logger
if (this.metricsManager && this.emailServer.deliverySystem) {
this.emailServer.deliverySystem.on('deliveryStart', (item: any) => {
this.metricsManager.trackEmailReceived(item?.from);
this.metricsManager!.trackEmailReceived(item?.from);
logger.log('info', `Email delivery started: ${item?.from}${item?.to}`, { zone: 'email' });
});
this.emailServer.deliverySystem.on('deliverySuccess', (item: any) => {
this.metricsManager.trackEmailSent(item?.to);
this.metricsManager!.trackEmailSent(item?.to);
logger.log('info', `Email delivered to ${item?.to}`, { zone: 'email' });
});
this.emailServer.deliverySystem.on('deliveryFailed', (item: any, error: any) => {
this.metricsManager.trackEmailFailed(item?.to, error?.message);
this.metricsManager!.trackEmailFailed(item?.to, error?.message);
logger.log('warn', `Email delivery failed to ${item?.to}: ${error?.message}`, { zone: 'email' });
});
}
if (this.metricsManager && this.emailServer) {
this.emailServer.on('bounceProcessed', () => {
this.metricsManager.trackEmailBounced();
this.metricsManager!.trackEmailBounced();
logger.log('warn', 'Email bounce processed', { zone: 'email' });
});
}
@@ -1305,12 +1305,12 @@ export class DcRouter {
}
logger.log('info', 'All unified email components stopped');
} catch (error) {
logger.log('error', `Error stopping unified email components: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `Error stopping unified email components: ${(error as Error).message}`);
throw error;
}
}
/**
* Update domain rules for email routing
* @param rules New domain rules to apply
@@ -1468,7 +1468,7 @@ export class DcRouter {
this.dnsServer.on('query', (event: plugins.smartdns.dnsServerMod.IDnsQueryCompletedEvent) => {
// Metrics tracking
for (const question of event.questions) {
this.metricsManager.trackDnsQuery(
this.metricsManager?.trackDnsQuery(
question.type,
question.name,
false,
@@ -1553,8 +1553,8 @@ export class DcRouter {
// Use the built-in socket handler from smartdns
// This handles HTTP/2, DoH protocol, etc.
await (this.dnsServer as any).handleHttpsSocket(socket);
} catch (error) {
logger.log('error', `DNS socket handler error: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `DNS socket handler error: ${(error as Error).message}`);
if (!socket.destroyed) {
socket.destroy();
}
@@ -1695,14 +1695,14 @@ export class DcRouter {
} else {
logger.log('warn', `Invalid DKIM record structure in ${file}`);
}
} catch (error) {
logger.log('error', `Failed to load DKIM record from ${file}: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `Failed to load DKIM record from ${file}: ${(error as Error).message}`);
}
}
} catch (error) {
logger.log('error', `Failed to load DKIM records: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `Failed to load DKIM records: ${(error as Error).message}`);
}
return records;
}
@@ -1734,11 +1734,11 @@ export class DcRouter {
// This ensures keys are ready even if DNS mode changes later
await dkimCreator.handleDKIMKeysForDomain(domainConfig.domain);
logger.log('info', `DKIM keys initialized for ${domainConfig.domain}`);
} catch (error) {
logger.log('error', `Failed to initialize DKIM for ${domainConfig.domain}: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `Failed to initialize DKIM for ${domainConfig.domain}: ${(error as Error).message}`);
}
}
logger.log('info', 'DKIM initialization complete');
}
@@ -1779,10 +1779,10 @@ export class DcRouter {
} else {
logger.log('warn', 'Could not auto-discover public IPv4 address');
}
} catch (error) {
logger.log('error', `Failed to auto-discover public IP: ${error.message}`);
} catch (error: unknown) {
logger.log('error', `Failed to auto-discover public IP: ${(error as Error).message}`);
}
if (!publicIp) {
logger.log('warn', 'No public IP available. Nameserver A records require either proxyIps, publicIp, or successful auto-discovery.');
}
@@ -1876,8 +1876,8 @@ export class DcRouter {
}
return null;
} catch (error) {
logger.log('warn', `Failed to detect public IP: ${error.message}`);
} catch (error: unknown) {
logger.log('warn', `Failed to detect public IP: ${(error as Error).message}`);
return null;
}
}
@@ -1911,8 +1911,8 @@ export class DcRouter {
const keyPem = plugins.fs.readFileSync(riCfg.tls.keyPath, 'utf8');
tlsConfig = { certPem, keyPem };
logger.log('info', 'Using explicit TLS cert/key for RemoteIngress tunnel');
} catch (err) {
logger.log('warn', `Failed to read RemoteIngress TLS cert/key files: ${err.message}`);
} catch (err: unknown) {
logger.log('warn', `Failed to read RemoteIngress TLS cert/key files: ${(err as Error).message}`);
}
}