skills/fp-ts-errors/SKILL.md
Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.
npx skillsauth add ranbot-ai/awesome-skills fp-ts-errorsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill teaches you how to handle errors without try/catch spaghetti. No academic jargon - just practical patterns for real problems.
The core idea: Errors are just data. Instead of throwing them into the void and hoping someone catches them, return them as values that TypeScript can track.
Exceptions are invisible in your types. They break the contract between functions.
// What this function signature promises:
function getUser(id: string): User
// What it actually does:
function getUser(id: string): User {
if (!id) throw new Error('ID required')
const user = db.find(id)
if (!user) throw new Error('User not found')
return user
}
// The caller has no idea this can fail
const user = getUser(id) // Might explode!
You end up with code like this:
// MESSY: try/catch everywhere
function processOrder(orderId: string) {
let order
try {
order = getOrder(orderId)
} catch (e) {
console.error('Failed to get order')
return null
}
let user
try {
user = getUser(order.userId)
} catch (e) {
console.error('Failed to get user')
return null
}
let payment
try {
payment = chargeCard(user.cardId, order.total)
} catch (e) {
console.error('Payment failed')
return null
}
return { order, user, payment }
}
import * as E from 'fp-ts/Either'
import { pipe } from 'fp-ts/function'
// Now TypeScript KNOWS this can fail
function getUser(id: string): E.Either<string, User> {
if (!id) return E.left('ID required')
const user = db.find(id)
if (!user) return E.left('User not found')
return E.right(user)
}
// The caller is forced to handle both cases
const result = getUser(id)
// result is Either<string, User> - error OR success, never both
Either<E, A> is simple: it holds either an error (E) or a value (A).
Left = error caseRight = success case (think "right" as in "correct")import * as E from 'fp-ts/Either'
// Creating values
const success = E.right(42) // Right(42)
const failure = E.left('Oops') // Left('Oops')
// Checking what you have
if (E.isRight(result)) {
console.log(result.right) // The success value
} else {
console.log(result.left) // The error
}
// Better: pattern match with fold
const message = pipe(
result,
E.fold(
(error) => `Failed: ${error}`,
(value) => `Got: ${value}`
)
)
// Wrap any throwing function with tryCatch
const parseJSON = (json: string): E.Either<Error, unknown> =>
E.tryCatch(
() => JSON.parse(json),
(e) => (e instanceof Error ? e : new Error(String(e)))
)
parseJSON('{"valid": true}') // Right({ valid: true })
parseJSON('not json') // Left(SyntaxError: ...)
// For functions you'll reuse, use tryCatchK
const safeParseJSON = E.tryCatchK(
JSON.parse,
(e) => (e instanceof Error ? e : new Error(String(e)))
)
import * as E from 'fp-ts/Either'
import { pipe } from 'fp-ts/function'
// Transform the success value
const doubled = pipe(
E.right(21),
E.map(n => n * 2)
) // Right(42)
// Transform the error
const betterError = pipe(
E.left('bad'),
E.mapLeft(e => `Error: ${e}`)
) // Left('Error: bad')
// Provide a default for errors
const value = pipe(
E.left('failed'),
E.getOrElse(() => 0)
) // 0
// Convert nullable to Either
const fromNullable = E.fromNullable('not found')
fromNullable(user) // Right(user) if exists, Left('not found') if null/undefined
The real power comes from chaining. Each step can fail, but you write it as a clean pipeline.
// MESSY: Each step can fail, nested try/catch everywhere
function processUserOrder(userId: string, productId: string): Result | null {
let user
try {
user = getUser(userId)
} catch (e) {
logError('User fetch failed', e)
return null
}
if (!user.isActive) {
logError('User not active')
return null
}
let product
try {
product = getProduct(productId)
} catch (e) {
logError('Product fetch failed', e)
return null
}
if (product.stock < 1) {
logError('Out of stock')
return null
}
let order
try {
order = createOrder(user, product)
} catch (e) {
logError('Order creation failed', e)
return null
}
return order
}
import * as E from 'fp-ts/Either
testing
Fix SEO indexing issues, crawl budget problems, and Search Console coverage errors for Next.js apps. Covers canonical tags, noindex audits, sitemap health, static rendering, and internal linking.
data-ai
Analyze AI disruption pressure across a business, map competitive exposure, and produce a 90-day defensive action plan.
tools
--- name: longbridge description: 125+ agent skills for Longbridge Securities — real-time quotes, charts, fundamentals, portfolio analysis, options, and more for HK/US/A-share/SG markets. Trilingual: Simplified Chinese, Traditional category: AI & Agents source: antigravity tags: [api, mcp, claude, ai, agent, security, cro] url: https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/longbridge --- # Longbridge ## Overview Longbridge is the official skill collection for Longbr
tools
Design, debug, and harden GitHub Actions CI/CD workflows, including reusable workflows, matrix builds, self-hosted runners, OIDC authentication, caching, environments, secrets, and release automation.