Skip to main content
doc0blade47/honodocumentation home
Sign in

Errors and Exceptions

Last updated Oct 12, 2026100% grounded

Overview

Handling errors cleanly and returning appropriate HTTP responses are crucial parts of building robust web applications. This guide covers how to manage application exceptions using HTTPException, catch unhandled errors with .onError(), customize missing page responses with .notFound(), and inspect errors inside your handlers and middleware using Context.


Using HTTPException for HTTP Status Codes

Basics of HTTPException

When fatal errors occur—such as authentication failures, bad inputs, or unauthorized access—you can throw an HTTPException. This class extends the native JavaScript Error class and accepts an HTTP status code along with optional configuration settings.

To import and use HTTPException:

import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
 
const app = new Hono()
 
app.post('/auth', async (c, next) => {
  const authorized = false // Example check
  if (!authorized) {
    throw new HTTPException(401, { message: 'Authentication required' })
  }
  await next()
})

HTTPException Options

When creating an HTTPException, you can pass an options object as the second argument:

Option KeyTypeDescription
messagestringOptional custom error message string.
resResponseOptional custom Response object to return directly.
causeunknownOptional underlying cause that triggered the error.

Tip

If you provide a custom Response via the res option, HTTPException automatically applies your status code and headers to that response when rendered.


Customizing Error Responses with .onError()

By default, unhandled errors produce a generic server response. You can capture and format all application errors globally using the .onError() method on your Hono instance.

import { Hono } from 'hono'
 
const app = new Hono()
 
app.onError((err, c) => {
  console.error(`Execution error: ${err.message}`)
  return c.json(
    {
      error: 'Internal Server Error',
      message: err.message,
    },
    500
  )
})
 
app.get('/fail', () => {
  throw new Error('Something went wrong!')
})

Customizing 404 Not Found Responses

When a request matches no defined routes, Hono triggers its fallback Not Found handler. You can customize this response across your application using the .notFound() method.

import { Hono } from 'hono'
 
const app = new Hono()
 
app.notFound((c) => {
  return c.json({ error: 'Resource not found', path: c.req.path }, 404)
})
 
app.get('/hello', (c) => c.text('Hello!'))

You can also trigger a Not Found response manually inside any handler using the Context helper:

app.get('/check', (c) => {
  const item = null
  if (!item) {
    return c.notFound()
  }
  return c.text('Found')
})

Accessing Errors in Middleware via Context

Middleware functions can inspect whether an error occurred further down the execution chain by checking c.error. This is useful for logging, cleanup tasks, or custom post-processing logic.

import { Hono } from 'hono'
 
const app = new Hono()
 
app.use('*', async (c, next) => {
  await next()
  
  if (c.error) {
    console.warn(`Captured error on path ${c.req.path}: ${c.error.message}`)
  }
})

Note

c.error holds the error object thrown by handlers or preceding middleware during the request lifecycle.

Was this page helpful?