0Pricing
TypeScript Academy · Lesson

Error middleware & result types

Design a central error handler and typed Result pattern; wrap async handlers to forward errors; return consistent error envelopes.

Intro

Goal: Centralize runtime errors and return a consistent JSON “error envelope”. You will create a Result type, an async handler wrapper, and a robust error middleware.

  • Discriminated Result<T,E>
  • next(err) from async handlers
  • Unknown→typed error mapping

Result type

Use a discriminated union for function results: { ok: true; value } or { ok: false; error }. Callers must handle both branches.

// Result pattern for services and controllers
export type Ok<T> = { ok: true; value: T }
export type Err<E> = { ok: false; error: E }
export type Result<T, E = string> = Ok<T> | Err<E>

export const ok = <T>(value: T): Ok<T> => ({ ok: true, value })
export const err = <E>(error: E): Err<E> => ({ ok: false, error })

// Example usage
async function getUserName(id: string): Promise<Result<string, "NOT_FOUND" | "DB">> {
  if (id === "missing") return err("NOT_FOUND")
  try { return ok("Ada") } catch { return err("DB") }
}

All lessons in this course

  1. Router handlers, Request/Response typing
  2. Schema validation with zod & inference to TS
  3. Error middleware & result types
← Back to TypeScript Academy