{"record":{"id":"faf8ef31c213459b","repo":"sickn33/agentic-awesome-skills","slug":"user-not-found-faf8ef","errorCode":null,"errorMessage":"User not found","messagePattern":"User not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/fp-errors/SKILL.md","lineNumber":45,"sourceCode":"- You want pragmatic fp-ts error-handling guidance for real application code.\n\n---\n\n## 1. Stop Throwing Everywhere\n\n### The Problem with Exceptions\n\nExceptions are invisible in your types. They break the contract between functions.\n\n```typescript\n// What this function signature promises:\nfunction getUser(id: string): User\n\n// What it actually does:\nfunction getUser(id: string): User {\n  if (!id) throw new Error('ID required')\n  const user = db.find(id)\n  if (!user) throw new Error('User not found')\n  return user\n}\n\n// The caller has no idea this can fail\nconst user = getUser(id) // Might explode!\n```\n\nYou end up with code like this:\n\n```typescript\n// MESSY: try/catch everywhere\nfunction processOrder(orderId: string) {\n  let order\n  try {\n    order = getOrder(orderId)\n  } catch (e) {\n    console.error('Failed to get order')\n    return null","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/sickn33/agentic-awesome-skills/blob/58d857988fcfac6986206bca2b2fe223aa437e4b/skills/fp-errors/SKILL.md#L27-L63","documentation":"Thrown by the same fp-errors skill example (skills/fp-errors/SKILL.md:45) when db.find(id) returns null/undefined: the requested user does not exist. The point of the doc is that the caller of getUser(id) has no way to know from the type that this call can explode.","triggerScenarios":"Calling getUser with a syntactically valid id that has no matching row: deleted accounts, stale ids from JWTs or URLs, race between existence check and lookup.","commonSituations":"Looking up users from decoded token sub claims after account deletion; following /users/:id links to removed records; test fixtures referencing seeded ids that were never inserted.","solutions":["Make absence a value: return Either of not-found or User (or Option of User) so callers must handle the missing case","If staying imperative, throw a typed NotFoundError and centralize a 404 mapper at the API boundary","Verify id provenance (token freshness, URL params) before lookup"],"exampleFix":"// before\nconst user = getUser(id) // Might explode!\n\n// after\nconst result = getUser(id)\nif (E.isLeft(result)) {\n  return handleMissingUser(result.left) // e.g. 404\n}","handlingStrategy":"type-guard","validationCode":"const maybeUser = await db.find(id)\nif (!maybeUser) return notFound(`no user with id ${id}`)","typeGuard":"const hasUser = (r: unknown): r is { user: User } =>\n  typeof r === 'object' && r !== null && 'user' in r","tryCatchPattern":"try {\n  const user = getUser(id)\n} catch (e) {\n  if (e instanceof Error && e.message === 'User not found') return notFound()\n  throw e\n}","preventionTips":["Prefer Either/Option returns for lookups that can miss","Map missing lookups to 404 at the API boundary","Verify id provenance (token sub, URL params) before lookup"],"tags":["entity-not-found","unchecked-exception","typescript"],"backgroundTag":"entity-not-found","analyzedSha":"58d857988fcfac6986206bca2b2fe223aa437e4b","analyzedAt":"2026-08-26T11:55:59.350Z","schemaVersion":2},"datasetVersion":"2026-08-26T14:46:13.012Z"}