Error Handling and Exceptions

Good error handling improves API reliability and developer experience.

Why it matters

  • Return clear error messages
  • Prevent unhandled crashes
  • Keep proper HTTP status codes
  • Make debugging easier

Basic approach with try/catch

@Get('/:id')
async getOne(@Param('id') id: string) {
try {
const userId = parseInt(id);
if (isNaN(userId)) {
return { success: false, message: 'ID must be a number' };
}
const user = await this.userService.getUserById(userId);
if (!user) {
return { success: false, message: 'User not found' };
}
return { success: true, data: user };
} catch (error) {
return {
success: false,
message: 'Internal server error',
error: error.message,
};
}
}

Throw HTTP errors with MidwayHttpError

import { MidwayHttpError } from '@midwayjs/core';
if (isNaN(userId)) {
throw new MidwayHttpError('ID must be a number', 400);
}
if (!user) {
throw new MidwayHttpError('User not found', 404);
}

Common status codes

CodeMeaningTypical use
400Bad RequestInvalid parameters
401UnauthorizedNot authenticated
403ForbiddenNo permission
404Not FoundResource missing
500Internal Server ErrorUnexpected server error

Custom error classes

import { MidwayHttpError } from '@midwayjs/core';
export class BusinessError extends MidwayHttpError {
constructor(message: string, code?: string) {
super(message, 400);
this.code = code || 'BUSINESS_ERROR';
}
code: string;
}
export class NotFoundError extends MidwayHttpError {
constructor(resource: string) {
super(`${resource} not found`, 404);
}
}

Summary

  • Validate input early
  • Throw meaningful HTTP errors
  • Keep response format consistent
  • Centralize handling with filters/middleware when possible
Powered by WebContainers
Files
Preparing Environment
  • npm install
  • npm run dev