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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(() => {})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user