sickn33/agentic-awesome-skills · error · Error
Failed to fetch user: ${error}
Error message
Failed to fetch user: ${error} What it means
The catch-all in fp-refactor's fetchUser: any failure inside the try block — the HTTP status throw, network rejection, JSON parse error, or validateUser throwing — is re-wrapped with a 'Failed to fetch user' prefix. This nesting loses the original error class, which the skill uses to argue for error values.
Source
Thrown at skills/fp-refactor/SKILL.md:171
4. **Replace return statements**: Convert `return value` to `E.right(value)`
5. **Remove try-catch blocks**: They're no longer needed
6. **Update callers**: Use `pipe` with `E.flatMap` to chain operations
### Pattern: Async try-catch to TaskEither
#### Before (Imperative)
```typescript
async function fetchUser(id: string): Promise<User> {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
return validateUser(data);
} catch (error) {
throw new Error(`Failed to fetch user: ${error}`);
}
}
async function fetchUserPosts(userId: string): Promise<Post[]> {
try {
const response = await fetch(`/api/users/${userId}/posts`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return await response.json();
} catch (error) {
throw new Error(`Failed to fetch posts: ${error}`);
}
}
// Complex orchestration with try-catch
async function getUserWithPosts(id: string): Promise<{ user: User; posts: Post[] } | null> {
try {View on GitHub (pinned to 58d857988f)
Solutions
- Preserve cause: throw new Error('Failed to fetch user', { cause: error }) instead of string-wrapping
- Inspect error.cause / inner message before this wrapper when debugging
- Use Either/TaskEither so each step tags its own failure without wrapping
Example fix
// before
catch (error) { throw new Error(`Failed to fetch user: ${error}`) }
// after (preserve cause, ES2022)
catch (error) {
throw new Error('Failed to fetch user', { cause: error })
} Defensive patterns
Strategy: try-catch
Try / catch
try {
await fetchUser(id)
} catch (e) {
// read e.cause (or the message suffix) for the real failure
const cause = (e as Error & { cause?: Error }).cause ?? e
} Prevention
- Wrap errors with { cause } to keep the root error
- Group telemetry on inner error class, not wrapper prefix
When it happens
Trigger: Any exception on the /api/users/:id path: offline network rejection, non-2xx status, malformed JSON body, or payload failing validateUser.
Common situations: Wrapping throws in wrapper throws so the root cause is buried; debugging becomes string-matching on message prefixes; monitoring groups unrelated failures under one message.
Related errors
- Failed to fetch posts: ${error}
- HTTP error: ${response.status}
- HTTP ${response.status}: ${response.statusText}
- HTTP ${response.status}
- HTTP ${posts.status}
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/2a3e3f3e18ce5f10.
Report an issue: GitHub.