Exceptions

Handle errors with structured HTTP exception classes.

MiiaJS provides a set of built-in exception classes that produce structured JSON error responses.

HttpException

The base class for all HTTP exceptions:

import { HttpException } from '@miiajs/core'

throw new HttpException(400, 'Invalid input', { field: 'email' })

Response:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid input",
  "details": { "field": "email" }
}

Constructor

new HttpException(statusCode: number, message: string, details?: any)

Built-in exceptions

ClassStatusDefault message
BadRequestException400Bad Request
UnauthorizedException401Unauthorized
ForbiddenException403Forbidden
NotFoundException404Not Found
ConflictException409Conflict
UnprocessableException422Unprocessable Entity
InternalServerException500Internal Server Error

Usage

import { NotFoundException, BadRequestException } from '@miiajs/core'

@Get('/:id')
async findOne(ctx: RequestContext) {
  const user = await this.userService.findById(ctx.params.id)
  if (!user) {
    throw new NotFoundException(`User ${ctx.params.id} not found`)
  }
  return user
}

@Post('/')
async create(ctx: RequestContext) {
  const exists = await this.userService.findByEmail(ctx.body.email)
  if (exists) {
    throw new ConflictException('Email already exists')
  }
  return this.userService.create(ctx.body)
}

Error handling

MiiaJS automatically catches all exceptions thrown in route handlers and middleware:

  • HttpException instances are returned with their status code and JSON body
  • All other errors are logged and returned as 500 Internal Server Error
// HttpException -> returned as-is
throw new NotFoundException('Not found')
// -> { statusCode: 404, error: "Not Found", message: "Not found" }

// Unknown error -> 500
throw new Error('something broke')
// -> { statusCode: 500, error: "Internal Server Error", message: "Internal Server Error" }

Custom error handling

Use middleware for custom error handling:

const errorHandler: Middleware = async (ctx, next) => {
  try {
    await next()
  } catch (error) {
    if (error instanceof HttpException) {
      ctx.res.status(error.statusCode).json(error.toJSON())
    } else {
      ctx.res.status(500).json({
        error: 'Unexpected error',
        requestId: ctx.req.headers.get('x-request-id'),
      })
    }
  }
}

app.use(errorHandler)