0Pricing
TypeScript Academy · บทเรียน

มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์

ออกแบบตัวจัดการข้อผิดพลาดส่วนกลางและรูปแบบ Result ที่มีชนิดข้อมูล ห่อหุ้มตัวจัดการ async เพื่อส่งต่อข้อผิดพลาด และส่งซองข้อผิดพลาดที่สอดคล้องกัน

มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์ เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

บทนำ

เป้าหมาย: รวมศูนย์ข้อผิดพลาดขณะทำงานและส่งคืน “โครงสร้างห่อหุ้มข้อผิดพลาด” ในรูป JSON ที่สอดคล้องกัน คุณจะสร้างชนิด ผลลัพธ์ ตัวห่อหุ้มตัวจัดการแบบไม่พร้อมกัน และมิดเดิลแวร์จัดการข้อผิดพลาดที่แข็งแกร่ง

  • Result<T,E> แบบแยกแยะได้
  • ส่งต่อ next(err) จากตัวจัดการแบบไม่พร้อมกัน
  • การแปลงค่าที่ไม่รู้จักเป็นข้อผิดพลาดที่มีชนิด

ชนิดผลลัพธ์

ใช้ยูเนียนแบบแยกแยะได้สำหรับผลลัพธ์ของฟังก์ชัน: { ok: true; value } หรือ { ok: false; error } ผู้เรียกต้องจัดการทั้งสองแขนง

// 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") }
}

โครงสร้างห่อหุ้มข้อผิดพลาด

ปรับค่าที่ไม่รู้จักให้อยู่ในโครงสร้างห่อหุ้มขนาดเล็กที่คาดเดาได้ หลีกเลี่ยงการเปิดเผยร่องรอยสแตกแก่ไคลเอ็นต์

// Canonical error envelope
export type ErrorEnvelope = {
  error: string
  code?: string
  details?: unknown
}

export function mapError(u: unknown): ErrorEnvelope {
  if (u instanceof Error) return { error: u.message }
  if (typeof u === "string") return { error: u }
  try { return { error: JSON.stringify(u) } } catch { return { error: "Unknown error" } }
}

ตัวห่อหุ้มแบบไม่พร้อมกันและมิดเดิลแวร์

ห่อตัวจัดการ แบบไม่พร้อมกัน ใด ๆ เพื่อให้การปฏิเสธเรียกใช้ next(err) มิดเดิลแวร์จัดการข้อผิดพลาดขั้นสุดท้ายจะจัดรูปแบบ JSON เพียงครั้งเดียว

import express, { Request, Response, NextFunction } from "express"

export const asyncHandler = <P, ResBody, ReqBody, Query>(fn: (req: Request<P, ResBody, ReqBody, Query>, res: Response<ResBody>, next: NextFunction) => Promise<unknown>) => {
  return (req: Request<P, ResBody, ReqBody, Query>, res: Response<ResBody>, next: NextFunction) => {
    Promise.resolve(fn(req, res, next)).catch(next)
  }
}

export function errorMiddleware(err: unknown, _req: Request, res: Response, _next: NextFunction) {
  const env = mapError(err)
  const status = env.code === "NOT_FOUND" ? 404 : 500
  res.status(status).json(env)
}

// Usage
// app.get("/", asyncHandler(async (req, res) => { throw new Error("boom") }))
// app.use(errorMiddleware)

เส้นทางและการผสานรวม

รวมการตรวจสอบและการจัดการข้อผิดพลาดเข้าด้วยกัน: การตรวจสอบจะส่งคืน 400 พร้อมรายละเอียด ส่วนการปฏิเสธอื่น ๆ จะถูกดักจับโดยมิดเดิลแวร์ส่วนกลาง

import express from "express"
import { z } from "zod"
import { asyncHandler, errorMiddleware } from "./errors"

const createUserSchema = z.object({ name: z.string().min(1) })

const app = express()
app.use(express.json())

app.post("/users", asyncHandler(async (req, res) => {
  const parsed = createUserSchema.safeParse(req.body)
  if (!parsed.success) {
    res.status(400).json({ error: "Invalid body", details: parsed.error.format() })
    return
  }
  res.status(201).json({ id: "u_1", name: parsed.data.name })
}))

app.use(errorMiddleware)

app.listen(3000, () => console.log("http://localhost:3000"))

เคล็ดลับ

เคล็ดลับ:

  • บันทึกรายละเอียดฝั่งเซิร์ฟเวอร์ และส่งข้อความขั้นต่ำกลับไปยังไคลเอ็นต์
  • เลือกใช้ ผลลัพธ์ที่มีชนิดในบริการ และแปลงเป็น HTTP ที่ขอบเขตของระบบ
  • อย่ากลืนการปฏิเสธทิ้ง—เรียกใช้ next(err) เสมอ

การตรวจสอบข้อผิดพลาดแบบไม่พร้อมกัน

ตรวจสอบอย่างรวดเร็ว: รูปแบบใดส่งต่อข้อผิดพลาดแบบไม่พร้อมกันได้อย่างถูกต้อง

สรุปทบทวน

สรุปทบทวน: ใช้ยูเนียน ผลลัพธ์สำหรับตรรกะของโดเมน ห่อตัวจัดการแบบไม่พร้อมกันให้เรียกใช้ next และจัดรูปแบบข้อผิดพลาดเพียงครั้งเดียวในมิดเดิลแวร์ขั้นสุดท้าย

คำถามที่พบบ่อย

บทเรียน “มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์”

ออกแบบตัวจัดการข้อผิดพลาดส่วนกลางและรูปแบบ Result ที่มีชนิดข้อมูล ห่อหุ้มตัวจัดการ async เพื่อส่งต่อข้อผิดพลาด และส่งซองข้อผิดพลาดที่สอดคล้องกัน คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน

บทเรียน “มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ตัวจัดการเราเตอร์และการกำหนดชนิดข้อมูล Request/Response
  2. การตรวจสอบสคีมาด้วย zod และการอนุมานเป็น TS
  3. มิดเดิลแวร์ข้อผิดพลาดและชนิดข้อมูลผลลัพธ์
← กลับไปที่ TypeScript Academy