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

  1. Preserve cause: throw new Error('Failed to fetch user', { cause: error }) instead of string-wrapping
  2. Inspect error.cause / inner message before this wrapper when debugging
  3. 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

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


AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26). Data as JSON: /api/errors/2a3e3f3e18ce5f10. Report an issue: GitHub.