Skip to content
youhoc
  • Pages
    • Home
    • Modern App Guidelines
    • Node.js
      • Installing & Exploring
      • Loading Modules
      • npm - Get Command Input
      • Express.js
        • Express Web Server
        • Template Engine & MVC
        • Authentication
        • Authentication Trong REST API Với JWT
        • File Upload with Multer, Express.js
        • Server-Side Validation Với Express-Validator
      • Sequelize
        • Sequelize Transactions: Đảm Bảo Tính Toàn Vẹn Dữ Liệu
        • 7 loại Data Types phổ biến Trong Sequelize
        • Phân Trang (Pagination) Trong Express.js Với Sequelize/MySQL
      • Hướng dẫn Cơ bản về Rest API
      • Node-cron Simple to Complex Setup with PM2
      • Hono
        • Hono Response
        • icon picker
          Error Handling
    • Cloudflare
      • Minimal Cloudflare Worker + Hono + Drizzle ORM (part 1)
      • Minimal Cloudflare Worker + Hono + Drizzle ORM (part 2)
    • htmx
      • HTMx Form: Request, Response, Swap
    • Linux
      • Day 1: Linux Distributions & Navigation
      • Day 2: User Management
      • Day 3: File Permission & Ownership
      • Day 4: Package Management
      • Day 5: Services Management
    • Javascript
      • JS The Weird Part
        • Execution Context
        • Types & Operators
        • Objects & Functions
        • Error Handling & Strict Mode
        • Typescript, ES6, Tra
      • Modern JS
        • JS in the Browser
        • Data Storage JSON
        • Modern JS
        • Advanced Objects & Methods
        • Webpack & Babel
        • Async
      • jQuery
        • In-depth Analysis of jQuery
      • React-ready JS
        • Arrow Function
        • Template Literals
        • Logical AND, OR, Ternary, Nullish Operators
        • Destructuring & Rest Operator
        • Array Method
        • Immutability and Spread Operator
        • Promises, Async/Await, Callback
    • Typescript
      • TypeScript cơ bản (phần 1)
      • TypeScript cơ bản (phần 2)
      • require vs import
    • ReactJS
      • React from Andrew
        • Summary from Next
        • 1. Basics
        • 2. React Components
        • 3. Webpack
        • 4. Styling with SCSS
        • 5. React Router
        • 6. React Hook
      • Modern React From The Beginning
        • Intro to JSX
        • Vite Build Tools
        • Basic Component Creation
        • Component State
        • Props & Component Composition
        • useState with Inputs & Form Submission
        • useEffect, useRef & Local Storage
        • Async / Await and Http Request in React
        • React Router: Declarative Mode
        • ContextAPI
        • React Router: Framework Mode
          • File-routing & HTML Layouts
          • Server-side Data Query
          • Links & Navigation
          • Loaders
    • PHP
      • gruntJS
      • composer
      • MySQL
      • Thiết lập Cloudflare Turnstile chống spam trong PHP
    • Docker
      • Container Basics
      • Container Networking
      • Container Image
      • Container Volume & Persistent Data
      • Dockerfile
      • Docker Compose
      • Docker Registry
    • Payload CMS

Error Handling

Xử lý Error trong Hono và Express
Bạn đang viết một REST API, mọi thứ chạy ổn. Rồi một ngày user gửi request với ID không tồn tại, token hết hạn, hoặc database bỗng dưng timeout — và app trả về… một trang lỗi trắng tinh, hoặc tệ hơn là crash luôn.
Xử lý error tốt không chỉ là try/catch cho qua — mà là biết log ở đâu, throw lên đâu, và trả về response lỗi nhất quán cho client. Bài này sẽ đi qua từng tình huống cụ thể, đối chiếu giữa Express và Hono.

Tư duy cốt lõi

Trước khi vào code, cần hiểu một nguyên tắc quan trọng:
Chỉ có handler mới có c (context) — chỉ handler mới trực tiếp trả được response.
Điều này nghĩa là:
Nếu lỗi xảy ra trong handlerreturn c.json() tại chỗ
Nếu lỗi xảy ra trong service/repository (không có c) → throw lên để handler bắt
Nếu muốn log và xử lý tập trung → dùng onError
Service/Repository Handler onError
│ │ │
│ throw Error() │ │
│──────────────────────>│ │
│ │ throw tiếp │
│ │───────────────────>│
│ │ │ log + return response

Cách 1: Xử lý lỗi tại chỗ trong Handler

Phù hợp khi logic đơn giản, lỗi có thể đoán trước ngay trong handler.
Hai cách viết gần như giống nhau, chỉ khác resc và phải return.

Cách 2: Throw từ Service, Handler bắt lại

Khi logic nằm ở service layer — không có c, không thể trả response trực tiếp.

Dùng Error thông thường

So sánh string để phân loại lỗi rất dễ gây bug — typo một chữ là sai hết.

Dùng HTTPException — Hono có sẵn

HTTPException giải quyết vấn đề trên bằng cách gắn status code trực tiếp vào error:

Custom Error Class trong Express — tương đương

Trong Express không có HTTPException sẵn, nhưng bạn có thể tự tạo tương tự:
HTTPException của Hono về bản chất cũng là pattern này — chỉ là có sẵn, không cần tự viết.

Cách 3: onError — Bắt lỗi tập trung

Khi app có nhiều routes, viết try/catch lặp đi lặp lại ở mỗi handler rất tẻ nhạt. Cả Express và Hono đều có cách bắt lỗi tập trung.
Khi dùng onError, handler không cần try/catch nữa — throw lên là onError tự bắt:
Lưu ý: Đặt app.onError ở cuối file, sau khi đã khai báo hết routes — tương tự error middleware của Express.

Kết hợp cả ba cách

Trong thực tế, bạn sẽ dùng cả ba tùy tình huống:

Best Practices

✅ Nên làm:
Dùng HTTPException (Hono) hoặc custom AppError (Express) khi throw từ service — để giữ status code theo cùng error
Đặt onError / error middleware ở cuối file, sau tất cả routes
Log error ở một chỗ duy nhất — trong onError, không phải rải rác ở từng handler
Trả về cùng một shape cho mọi error response: { message: string }
❌ Tránh:

Tóm tắt

Tình huống
Express
Hono
Lỗi đơn giản trong handler
res.status(404).json()
return c.json({}, 404)
Throw từ service kèm status
Custom AppError
HTTPException
Bắt lỗi tập trung
Error middleware (4 params)
app.onError((err, c) => {})
Log tập trung
Trong error middleware
Trong app.onError
There are no rows in this table
Nguyên tắc cốt lõi không đổi dù dùng Express hay Hono: throw lỗi có status code từ service, bắt và trả response ở handler hoặc onError, log một chỗ duy nhất.
Bước tiếp theo: Khi đã nắm error handling, bạn có thể tìm hiểu thêm về Validation với Zod (@hono/zod-validator) để bắt lỗi input từ sớm trước khi vào service, và Logging middleware để ghi lại mọi request/response một cách có hệ thống.
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.