- Added YAML frontmatter to all 8 polish-* skills and sweep skill so Claude can auto-invoke them - New bitcoin-conventions skill with PROUX UX methodology, sats display, address validation, Tor preferences, Lightning patterns - Path-specific rules for containers (security hardening) and frontend (Vue/glassmorphism conventions) - Gitea Actions: nightly security review and weekly dependency audit Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
88 lines
2.8 KiB
Markdown
88 lines
2.8 KiB
Markdown
---
|
|
name: polish-errors
|
|
description: Fix silent error handling across Archipelago codebase. Replaces empty catch blocks, adds user-visible error feedback for all async operations. Use when user says "polish errors", "fix error handling", "silent catches", or "error feedback".
|
|
---
|
|
|
|
# Skill: Polish Error Handling
|
|
|
|
Fix silent error handling patterns across the entire codebase. Every async operation must have visible, actionable error feedback for the user.
|
|
|
|
## What to Fix
|
|
|
|
### Frontend (neode-ui/src/)
|
|
|
|
1. **Silent catch blocks**: Find and replace all `.catch(() => {})` patterns
|
|
- Search: `grep -rn "catch.*=>.*{}" --include="*.vue" --include="*.ts" src/`
|
|
- Replace with: proper error logging + user-visible feedback (toast, inline error, or modal)
|
|
- Pattern:
|
|
```typescript
|
|
.catch((err) => {
|
|
console.error('[ComponentName] operation failed:', err)
|
|
errorMessage.value = formatError(err)
|
|
})
|
|
```
|
|
|
|
2. **Unhandled router.push**: Find `router.push(...).catch(() => {})`
|
|
- Replace with: `router.push(...).catch(console.error)` minimum
|
|
- Or handle NavigationDuplicated gracefully
|
|
|
|
3. **Silent try/catch**: Find `try { ... } catch { /* empty */ }`
|
|
- Every catch block must either: log the error, show user feedback, or explicitly comment why it's safe to ignore
|
|
|
|
4. **Missing error states**: For each view, verify:
|
|
- `ref<string | null>` error variable exists
|
|
- Error is displayed in template (inline message, not just console)
|
|
- Error clears on retry or navigation
|
|
|
|
### Backend (core/)
|
|
|
|
5. **Silent error swallowing**: Find `unwrap_or_default()` on serialization
|
|
- Replace with proper error propagation or logging
|
|
- Pattern: `.map_err(|e| anyhow::anyhow!("Serialization failed: {}", e))?`
|
|
|
|
6. **Error response consistency**: All RPC errors should use:
|
|
- Consistent error codes (not random negative numbers)
|
|
- Human-readable messages
|
|
- Consistent JSON structure
|
|
|
|
## Verification
|
|
|
|
After fixes, run:
|
|
```bash
|
|
# Zero silent catches
|
|
grep -rn "catch.*=>.*{}\|catch\s*{" neode-ui/src/ --include="*.vue" --include="*.ts" | grep -v node_modules | grep -v "console\|error\|log\|warn"
|
|
|
|
# Zero empty catch blocks
|
|
grep -rn "catch.*{$" neode-ui/src/ --include="*.vue" --include="*.ts" -A1 | grep -P "^\d+-\s*\}"
|
|
```
|
|
|
|
Both should return zero results.
|
|
|
|
## Error Display Pattern
|
|
|
|
Use this consistent pattern for user-facing errors:
|
|
```typescript
|
|
const errorMessage = ref<string | null>(null)
|
|
|
|
async function doAction() {
|
|
errorMessage.value = null
|
|
try {
|
|
await rpcClient.someCall()
|
|
} catch (err) {
|
|
errorMessage.value = err instanceof Error ? err.message : 'Operation failed'
|
|
}
|
|
}
|
|
```
|
|
|
|
Template:
|
|
```vue
|
|
<p v-if="errorMessage" class="text-red-400 text-sm mt-2">{{ errorMessage }}</p>
|
|
```
|
|
|
|
## Deploy After Fixes
|
|
|
|
Always deploy and verify on live server after making changes:
|
|
```bash
|
|
./scripts/deploy-to-target.sh --live
|
|
```
|