fix: replace silent error swallowing with console.warn and user-facing error messages
All empty catch blocks across 8 Vue pages now log warnings. User-initiated actions (fight, matchmake) also surface errors in the UI via fightError/loadError refs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a4008bcf88
commit
c98007e95c
@@ -53,7 +53,9 @@ async function triggerFight() {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
router.push(`/arena/${data.fightId}`)
|
router.push(`/arena/${data.fightId}`)
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[Arena] triggerFight failed:', err)
|
||||||
|
}
|
||||||
isMocking.value = false
|
isMocking.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ const waitingFighters = ref<QueueEntry[]>([])
|
|||||||
let pollHandle: ReturnType<typeof setInterval> | null = null
|
let pollHandle: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
const isOwner = ref(false)
|
const isOwner = ref(false)
|
||||||
|
const loadError = ref('')
|
||||||
|
const fightError = ref('')
|
||||||
const showCustomize = ref(false)
|
const showCustomize = ref(false)
|
||||||
const isSaving = ref(false)
|
const isSaving = ref(false)
|
||||||
const custError = ref('')
|
const custError = ref('')
|
||||||
@@ -207,7 +209,11 @@ onMounted(async () => {
|
|||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/bots/${encodeURIComponent(botName)}/stats`)
|
const res = await fetch(`/api/bots/${encodeURIComponent(botName)}/stats`)
|
||||||
if (res.ok) stats.value = await res.json()
|
if (res.ok) stats.value = await res.json()
|
||||||
} catch { /* */ }
|
else loadError.value = `Failed to load bot (${res.status})`
|
||||||
|
} catch (err) {
|
||||||
|
loadError.value = 'Network error loading bot profile'
|
||||||
|
console.warn('[BotProfile] load failed:', err)
|
||||||
|
}
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
|
|
||||||
// Check ownership
|
// Check ownership
|
||||||
@@ -229,32 +235,46 @@ async function pollQueue() {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
waitingFighters.value = data.queue || []
|
waitingFighters.value = data.queue || []
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[BotProfile] queue poll failed:', err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function instantFight() {
|
async function instantFight() {
|
||||||
if (!stats.value || isJoining.value) return
|
if (!stats.value || isJoining.value) return
|
||||||
isJoining.value = true
|
isJoining.value = true
|
||||||
|
fightError.value = ''
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/queue/join/${stats.value.id}`, { method: 'POST' })
|
const res = await fetch(`/api/queue/join/${stats.value.id}`, { method: 'POST' })
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
router.push(`/arena/${data.fightId}`)
|
router.push(`/arena/${data.fightId}`)
|
||||||
|
} else {
|
||||||
|
fightError.value = `Matchmaking failed (${res.status})`
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
fightError.value = 'Network error starting fight'
|
||||||
|
console.warn('[BotProfile] instant fight failed:', err)
|
||||||
|
}
|
||||||
isJoining.value = false
|
isJoining.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fightSpecific(opponentBotId: string) {
|
async function fightSpecific(opponentBotId: string) {
|
||||||
if (!stats.value || isJoining.value) return
|
if (!stats.value || isJoining.value) return
|
||||||
isJoining.value = true
|
isJoining.value = true
|
||||||
|
fightError.value = ''
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/fights/matchmake/${stats.value.id}`, { method: 'POST' })
|
const res = await fetch(`/api/fights/matchmake/${stats.value.id}`, { method: 'POST' })
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
router.push(`/arena/${data.fightId}`)
|
router.push(`/arena/${data.fightId}`)
|
||||||
|
} else {
|
||||||
|
fightError.value = `Matchmaking failed (${res.status})`
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
fightError.value = 'Network error starting fight'
|
||||||
|
console.warn('[BotProfile] fight specific failed:', err)
|
||||||
|
}
|
||||||
isJoining.value = false
|
isJoining.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +295,7 @@ const tierClass = (t: number) => `tier-${t}`
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="!stats" class="flex-1 flex items-center justify-center">
|
<div v-else-if="!stats" class="flex-1 flex items-center justify-center">
|
||||||
<p class="font-display text-text-muted">Bot not found.</p>
|
<p class="font-display text-text-muted">{{ loadError || 'Bot not found.' }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -426,6 +446,8 @@ const tierClass = (t: number) => `tier-${t}`
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p v-if="fightError" class="font-mono text-[10px] text-neon-pink mt-2">{{ fightError }}</p>
|
||||||
|
|
||||||
<!-- Choose your fight panel -->
|
<!-- Choose your fight panel -->
|
||||||
<div v-if="showChoose" class="mt-3 border border-border bg-surface-raised/50 p-3">
|
<div v-if="showChoose" class="mt-3 border border-border bg-surface-raised/50 p-3">
|
||||||
<p class="font-display text-[10px] font-bold text-text-muted tracking-[0.15em] mb-2">
|
<p class="font-display text-[10px] font-bold text-text-muted tracking-[0.15em] mb-2">
|
||||||
|
|||||||
@@ -192,7 +192,9 @@ async function loadFight(): Promise<string | null> {
|
|||||||
}
|
}
|
||||||
return data.status
|
return data.status
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] loadFight failed:', err)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +256,9 @@ async function pollForChallenge() {
|
|||||||
} else if (humanSubmitted.value) {
|
} else if (humanSubmitted.value) {
|
||||||
humanChallenge.value = null
|
humanChallenge.value = null
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] pollForChallenge failed:', err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startTimer() {
|
function startTimer() {
|
||||||
@@ -287,7 +291,9 @@ async function submitHumanAnswer() {
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ answer: humanAnswer.value.trim() }),
|
body: JSON.stringify({ answer: humanAnswer.value.trim() }),
|
||||||
})
|
})
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] submitHumanAnswer failed:', err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Live scene management ---
|
// --- Live scene management ---
|
||||||
@@ -350,7 +356,9 @@ function connectSSE() {
|
|||||||
color: 'neon-green',
|
color: 'neon-green',
|
||||||
})
|
})
|
||||||
scrollLiveLog()
|
scrollLiveLog()
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] SSE round_start parse failed:', err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
eventSource.addEventListener('human_challenge', async (e) => {
|
eventSource.addEventListener('human_challenge', async (e) => {
|
||||||
@@ -377,19 +385,25 @@ function connectSSE() {
|
|||||||
} else {
|
} else {
|
||||||
applyChallenge(sseData)
|
applyChallenge(sseData)
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] SSE human_challenge failed:', err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
eventSource.addEventListener('round_end', (e) => {
|
eventSource.addEventListener('round_end', (e) => {
|
||||||
try {
|
try {
|
||||||
handleRoundEnd(JSON.parse(e.data))
|
handleRoundEnd(JSON.parse(e.data))
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] SSE round_end failed:', err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
eventSource.addEventListener('fight_end', (e) => {
|
eventSource.addEventListener('fight_end', (e) => {
|
||||||
try {
|
try {
|
||||||
handleFightEnd(JSON.parse(e.data))
|
handleFightEnd(JSON.parse(e.data))
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] SSE fight_end failed:', err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let sseRetries = 0
|
let sseRetries = 0
|
||||||
@@ -492,7 +506,9 @@ async function handleRoundEnd(data: any) {
|
|||||||
botAScore: result.botAScore || 0,
|
botAScore: result.botAScore || 0,
|
||||||
botBScore: result.botBScore || 0,
|
botBScore: result.botBScore || 0,
|
||||||
})
|
})
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[FightPage] playRound animation failed:', err)
|
||||||
|
}
|
||||||
|
|
||||||
if (aWon || bWon) {
|
if (aWon || bWon) {
|
||||||
await liveScene.playTaunt(aWon ? 'a' : 'b')
|
await liveScene.playTaunt(aWon ? 'a' : 'b')
|
||||||
@@ -679,8 +695,13 @@ async function fightAgain(botId: string) {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
if (liveFightData.value) await initLiveScene()
|
if (liveFightData.value) await initLiveScene()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fightError.value = `Failed to start fight (${res.status})`
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
fightError.value = 'Network error starting fight'
|
||||||
|
console.warn('[FightPage] fightAgain failed:', err)
|
||||||
|
}
|
||||||
isRequeueing.value = false
|
isRequeueing.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,8 +720,13 @@ async function matchmake(botId: string) {
|
|||||||
fightError.value = ''
|
fightError.value = ''
|
||||||
window.history.replaceState({}, '', `/arena/${data.fightId}`)
|
window.history.replaceState({}, '', `/arena/${data.fightId}`)
|
||||||
startPolling()
|
startPolling()
|
||||||
|
} else {
|
||||||
|
fightError.value = `Matchmaking failed (${res.status})`
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
fightError.value = 'Network error during matchmaking'
|
||||||
|
console.warn('[FightPage] matchmake failed:', err)
|
||||||
|
}
|
||||||
isRequeueing.value = false
|
isRequeueing.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -304,7 +304,9 @@ onMounted(async () => {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
recentFights.value = data.slice(0, 4)
|
recentFights.value = data.slice(0, 4)
|
||||||
}
|
}
|
||||||
} catch { /* server not running */ }
|
} catch (err) {
|
||||||
|
console.warn('[Home] load fights failed:', err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|||||||
@@ -171,7 +171,9 @@ async function loadFight() {
|
|||||||
enemyHp.value = amSideA.value ? data.botBHp : data.botAHp
|
enemyHp.value = amSideA.value ? data.botBHp : data.botAHp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[HumanFight] poll failed:', err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function watchReplay() {
|
function watchReplay() {
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ async function pollQueue() {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
queueCount.value = data.waiting
|
queueCount.value = data.waiting
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[JoinBout] queue poll failed:', err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleLogin() {
|
async function handleLogin() {
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ onMounted(async () => {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
bots.value = data.sort((a: Bot, b: Bot) => b.eloRating - a.eloRating)
|
bots.value = data.sort((a: Bot, b: Bot) => b.eloRating - a.eloRating)
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[Leaderboard] load failed:', err)
|
||||||
|
}
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ onMounted(async () => {
|
|||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
bots.value = data.sort((a: Bot, b: Bot) => b.eloRating - a.eloRating)
|
bots.value = data.sort((a: Bot, b: Bot) => b.eloRating - a.eloRating)
|
||||||
}
|
}
|
||||||
} catch { /* */ }
|
} catch (err) {
|
||||||
|
console.warn('[Schedule] load bots failed:', err)
|
||||||
|
}
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user