feat: Improve error logging and validation across various flows and utilities

This commit is contained in:
2025-11-09 18:05:43 +01:00
parent 9fb5911fa2
commit 2c55fff61d
8 changed files with 128 additions and 34 deletions

View File

@@ -139,6 +139,17 @@ function determineColorFromContent(content: string): number {
return DISCORD.COLOR_GRAY
}
/**
* Type guard to check if config has valid logging configuration
*/
function hasValidLogging(config: unknown): config is { logging: { excludeFunc?: string[]; webhookExcludeFunc?: string[] } } {
return typeof config === 'object' &&
config !== null &&
'logging' in config &&
typeof config.logging === 'object' &&
config.logging !== null
}
function enqueueWebhookLog(url: string, line: string) {
const buf = getBuffer(url)
buf.lines.push(line)
@@ -164,9 +175,8 @@ function enqueueWebhookLog(url: string, line: string) {
export function log(isMobile: boolean | 'main', title: string, message: string, type: 'log' | 'warn' | 'error' = 'log', color?: keyof typeof chalk): Error | void {
const configData = loadConfig()
// Access logging config with fallback for backward compatibility
const configAny = configData as unknown as Record<string, unknown>
const logging = configAny.logging as { excludeFunc?: string[]; logExcludeFunc?: string[] } | undefined
// Access logging config with type guard for safer access
const logging = hasValidLogging(configData) ? configData.logging : undefined
const logExcludeFunc = logging?.excludeFunc ?? (configData as { logExcludeFunc?: string[] }).logExcludeFunc ?? []
if (logExcludeFunc.some((x: string) => x.toLowerCase() === title.toLowerCase())) {
@@ -178,7 +188,7 @@ export function log(isMobile: boolean | 'main', title: string, message: string,
// Clean string for notifications (no chalk, structured)
type LoggingCfg = { excludeFunc?: string[]; webhookExcludeFunc?: string[]; redactEmails?: boolean }
const loggingCfg: LoggingCfg = (configAny.logging || {}) as LoggingCfg
const loggingCfg: LoggingCfg = logging || {}
const shouldRedact = !!loggingCfg.redactEmails
const redact = (s: string) => shouldRedact ? s.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/ig, (m) => {
const [u, d] = m.split('@'); return `${(u||'').slice(0,2)}***@${d||''}`
@@ -269,7 +279,7 @@ export function log(isMobile: boolean | 'main', title: string, message: string,
// Webhook streaming (live logs)
try {
const loggingCfg: Record<string, unknown> = (configAny.logging || {}) as Record<string, unknown>
const loggingCfg: Record<string, unknown> = (logging || {}) as Record<string, unknown>
const webhookCfg = configData.webhook
const liveUrlRaw = typeof loggingCfg.liveWebhookUrl === 'string' ? loggingCfg.liveWebhookUrl.trim() : ''
const liveUrl = liveUrlRaw || (webhookCfg?.enabled && webhookCfg.url ? webhookCfg.url : '')

View File

@@ -123,6 +123,11 @@ export class Util {
return []
}
// Check for undefined/null elements which could cause issues downstream
if (arr.some(item => item === undefined || item === null)) {
throw new Error('Array contains undefined or null elements which are not allowed.')
}
if (!Number.isFinite(numChunks) || numChunks <= 0) {
throw new Error(`Invalid numChunks: ${numChunks}. Must be a positive finite number.`)
}