Skip to content

Error Classes

LightTs provides HttpError and specific error classes like ConflictError and BadRequestError to standardize error handling. Generated by lts add responses, these classes and a middleware handler ensure consistent error responses using native Node.js and Express.

The lts add responses command adds the following to src/core/errors/, using kebab-case for file names:

  • Directorysrc/
    • Directorycore/
      • Directoryerrors/
        • bad-request.error.ts
        • conflict.error.ts
        • forbidden.error.ts
        • handler.error.ts
        • index.ts
        • not-found.error.ts
        • server-error.error.ts
        • unauthorized.error.ts

These classes use camelCase for methods and variables, supporting common HTTP errors.

src/core/errors/index.ts
import { Request, Response } from 'express';
export class HttpError extends Error {
public readonly statusCode: number;
public readonly details?: any;
constructor(statusCode: number, message: string, details?: any) {
super(message);
this.statusCode = statusCode;
this.details = details;
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
static middleware(err: any, req: Request, res: Response) {
const statusCode = err.statusCode || 500;
res.status(statusCode).json({
success: false,
message: err.message || 'internal server error'
});
}
}

Add the error middleware to your application:

index.ts
import { HttpError } from '@/core/errors';
...
// Error middleware
app.use(HttpError.middleware);
...

Throw error classes in your services, paired with a simple controller (Express Router).

src/modules/user/user.service.ts
import { BadRequestError } from '@/core/errors/bad-request.error';
import { ConflictError } from '@/core/errors/conflict.error';
import { DataResponse } from '@/core/responses/data.response';
import { MessageResponse } from '@/core/responses/message.response';
import { Request, Response } from 'express';
export default {
getUsers: async (req: Request, res: Response) => {
const users = [{ id: 1, name: 'John Doe' }];
return new DataResponse(res, {
data: users,
message: 'Users fetched!',
statusCode: 200,
});
},
createUser: async (req: Request, res: Response) => {
const { email } = req.body;
if (!email) throw new BadRequestError('Email is required!');
if (email === '[email protected]') throw new ConflictError('Email already exists!');
return new MessageResponse(res, { message: 'User created!', statusCode: 201 });
},
};
  • Customization: Extend HttpError in src/core/errors/ for custom error types.
  • Naming Conventions: Files use kebab-case (e.g., conflict.error.ts), classes and methods use camelCase (e.g., ConflictError, throwError).
  • Error Handling: Place HttpError.middleware last in src/index.ts to catch all errors.
  • Available Errors: Includes BadRequestError (400), ConflictError (409), ForbiddenError (403), NotFoundError (404), UnauthorizedError (401), and ServerError (500).