fix: add dev-mode warnings to all 24 silent catch blocks

Every empty/comment-only catch block now logs a descriptive warning
in dev mode via `if (import.meta.env.DEV) console.warn(...)`. Covers
15 files across views, stores, components, and utils. Zero silent
catches remaining.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-11 00:58:55 +00:00
parent 7a7cbf1da3
commit bc879b3581
16 changed files with 45 additions and 43 deletions

View File

@@ -66,7 +66,7 @@
- [x] **QUAL-01** — Run full sweep and record baseline. Execute `/sweep` skill. Record the initial violation counts in `docs/quality-baseline.md`. This becomes the regression target -- violation counts must only go down, never up. **Acceptance**: Baseline document exists with all metrics.
- [ ] **QUAL-02** — Fix all silent catch blocks. Grep for empty catch blocks across `neode-ui/src/`. Each silent catch should either: log in dev mode (`if (import.meta.env.DEV) console.warn(...)`), re-throw, or handle the error in the UI. Target: zero silent catches. **Acceptance**: `/sweep` "Silent catches" = PASS.
- [x] **QUAL-02** — Fix all silent catch blocks. Grep for empty catch blocks across `neode-ui/src/`. Each silent catch should either: log in dev mode (`if (import.meta.env.DEV) console.warn(...)`), re-throw, or handle the error in the UI. Target: zero silent catches. **Acceptance**: `/sweep` "Silent catches" = PASS.
- [ ] **QUAL-03** — Remove all console.log in production paths. Grep for `console.log` in `neode-ui/src/**/*.{ts,vue}` excluding dev-gated lines. Wrap each in `if (import.meta.env.DEV)` or replace with proper error handling. **Acceptance**: `/sweep` "Console.log" = PASS.

View File

@@ -302,7 +302,7 @@ export class WebSocketClient {
try {
this.ws.close()
} catch (e) {
// Ignore errors
if (import.meta.env.DEV) console.warn('WebSocket close error', e)
}
this.ws = null
}

View File

@@ -255,8 +255,8 @@ function checkIframeContent() {
if (!body || (body.children.length === 0 && body.innerText.trim() === '')) {
iframeBlocked.value = true
}
} catch {
// Cross-origin: can't access, assume working
} catch (e) {
if (import.meta.env.DEV) console.warn('Cross-origin: can\'t access iframe, assume working', e)
}
}
@@ -289,8 +289,8 @@ async function sendIdentityIfSupported() {
challenge,
signature: sigRes.signature
}, '*')
} catch {
// Identity not available — continue without it
} catch (e) {
if (import.meta.env.DEV) console.warn('Identity not available — continuing without it', e)
}
}

View File

@@ -178,7 +178,8 @@ function loadSavedPosition() {
} else {
savedPosition.value = null
}
} catch {
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to load saved CLI position', e)
savedPosition.value = null
}
}
@@ -187,8 +188,8 @@ function savePosition(x: number, y: number) {
savedPosition.value = { x, y }
try {
localStorage.setItem(SAVED_POSITION_KEY, JSON.stringify({ x, y }))
} catch {
// ignore
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to save CLI position', e)
}
}

View File

@@ -191,7 +191,8 @@ function loadSavedPosition() {
} else {
savedPosition.value = null
}
} catch {
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to load saved spotlight position', e)
savedPosition.value = null
}
}
@@ -200,8 +201,8 @@ function savePosition(x: number, y: number) {
savedPosition.value = { x, y }
try {
localStorage.setItem(SAVED_POSITION_KEY, JSON.stringify({ x, y }))
} catch {
// ignore
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to save spotlight position', e)
}
}

View File

@@ -173,8 +173,8 @@ onMounted(async () => {
}
}
}
} catch {
// Not shared yet, defaults are fine
} catch (e) {
if (import.meta.env.DEV) console.warn('Not shared yet, defaults are fine', e)
}
})

View File

@@ -95,8 +95,8 @@ export const useAIPermissionsStore = defineStore('aiPermissions', () => {
const parsed = JSON.parse(stored) as AIContextCategory[]
return new Set(parsed.filter(c => AI_PERMISSION_CATEGORIES.some(cat => cat.id === c)))
}
} catch {
// ignore
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to load AI permissions from storage', e)
}
return new Set()
}

View File

@@ -41,8 +41,8 @@ export const useSpotlightStore = defineStore('spotlight', () => {
recentItems.value = [withTimestamp, ...filtered].slice(0, MAX_RECENT_ITEMS)
try {
localStorage.setItem(RECENT_ITEMS_KEY, JSON.stringify(recentItems.value))
} catch {
// Ignore storage errors
} catch (e) {
if (import.meta.env.DEV) console.warn('Failed to save recent items to storage', e)
}
}

View File

@@ -9,8 +9,8 @@ export const useWeb5BadgeStore = defineStore('web5Badge', () => {
try {
const res = await rpcClient.call<{ requests: Array<{ id: string }> }>({ method: 'network.list-requests' })
pendingRequestCount.value = res.requests?.length ?? 0
} catch {
// ignore — badge is best-effort
} catch (e) {
if (import.meta.env.DEV) console.warn('Badge refresh failed — best-effort', e)
}
}

View File

@@ -40,7 +40,7 @@ export async function fetchGitHubAppInfo(repoUrl: string, appId: string): Promis
targetRepo = start9RepoName
}
} catch (e) {
// Fall back to original repo
if (import.meta.env.DEV) console.warn('Start9 repo lookup failed, falling back to original repo', e)
}
}
@@ -90,7 +90,7 @@ export async function fetchGitHubAppInfo(repoUrl: string, appId: string): Promis
}
}
} catch (e) {
// Try next path
if (import.meta.env.DEV) console.warn('Icon path lookup failed, trying next path', e)
}
}
@@ -108,7 +108,7 @@ export async function fetchGitHubAppInfo(repoUrl: string, appId: string): Promis
}
}
} catch (e) {
// No icon from releases
if (import.meta.env.DEV) console.warn('No icon from releases', e)
}
}
@@ -132,7 +132,7 @@ export async function fetchGitHubAppInfo(repoUrl: string, appId: string): Promis
break
}
} catch (e) {
// Try next URL
if (import.meta.env.DEV) console.warn('Raw icon URL failed, trying next URL', e)
}
}
}

View File

@@ -172,8 +172,8 @@ async function loadCounts() {
sectionCounts.value[section.id] = 0
}
}
} catch {
// Silently fail
} catch (e) {
if (import.meta.env.DEV) console.warn('FileBrowser count loading failed silently', e)
}
}

View File

@@ -523,8 +523,8 @@ onMounted(async () => {
const usage = await fileBrowserClient.getUsage()
cloudStorageUsed.value = usage.totalSize
cloudFolderCount.value = usage.folderCount
} catch {
// FileBrowser may not be running — leave as loading
} catch (e) {
if (import.meta.env.DEV) console.warn('FileBrowser may not be running', e)
}
loadSystemStats()
systemStatsInterval = setInterval(loadSystemStats, 30000)
@@ -583,8 +583,8 @@ async function loadSystemStats() {
systemStats.diskTotal = res.disk_total_bytes
systemStats.diskPercent = res.disk_total_bytes > 0 ? (res.disk_used_bytes / res.disk_total_bytes) * 100 : 0
systemStats.uptimeSecs = res.uptime_secs
} catch {
// RPC unavailable — keep defaults
} catch (e) {
if (import.meta.env.DEV) console.warn('RPC unavailable — keeping defaults', e)
}
}

View File

@@ -97,8 +97,8 @@ function selectOption(option: string) {
async function proceed() {
try {
await completeOnboarding()
} catch {
// localStorage fallback in completeOnboarding ensures onboarding is marked complete
} catch (e) {
if (import.meta.env.DEV) console.warn('completeOnboarding failed, localStorage fallback ensures onboarding is marked complete', e)
}
router.push('/login').catch(() => {})
}

View File

@@ -387,8 +387,8 @@ async function loadNetworkData() {
const count = fwdRes.value.forwards?.length ?? 0
networkData.value.forwardCount = `${count} rule${count !== 1 ? 's' : ''}`
}
} catch {
// Keep N/A defaults on failure
} catch (e) {
if (import.meta.env.DEV) console.warn('Keep N/A defaults on failure', e)
} finally {
networkLoading.value = false
}

View File

@@ -684,8 +684,8 @@ async function loadTotpStatus() {
try {
const res = await rpcClient.totpStatus()
totpEnabled.value = res.enabled
} catch {
// Ignore - may not be available
} catch (e) {
if (import.meta.env.DEV) console.warn('TOTP status may not be available', e)
}
}
@@ -873,14 +873,14 @@ onMounted(async () => {
try {
const res = await rpcClient.getTorAddress()
torAddressFromRpc.value = res.tor_address ?? null
} catch {
// Ignore - tor address may not be available yet
} catch (e) {
if (import.meta.env.DEV) console.warn('Tor address may not be available yet', e)
}
}
})
async function handleLogout() {
try { await store.logout() } catch { /* proceed */ }
try { await store.logout() } catch (e) { if (import.meta.env.DEV) console.warn('Logout failed, proceeding anyway', e) }
router.push('/login').catch(() => { window.location.href = '/login' })
}
</script>

View File

@@ -1764,8 +1764,8 @@ async function revokeCredential(id: string) {
try {
await rpcClient.call({ method: 'identity.revoke-credential', params: { id } })
await loadCredentials()
} catch {
// Silent fail for revocation
} catch (e) {
if (import.meta.env.DEV) console.warn('Silent fail for revocation', e)
}
}
@@ -2016,8 +2016,8 @@ async function discoverAndAddPeers() {
if (n.onion && n.pubkey) {
try {
await rpcClient.addPeer({ onion: n.onion, pubkey: n.pubkey })
} catch {
// may already exist
} catch (e) {
if (import.meta.env.DEV) console.warn('Peer may already exist', e)
}
}
}