Exception Handling
This module provides a robust and structured way to handle HTTP exceptions in your AdonisJS application. It includes a base `HTTPException` class, a list of pre-defined common HTTP exceptions, and a parser to convert various error types into a consistent format.
HTTPException
The HTTPException
class is the cornerstone of the exception handling system. It extends the AdonisJS Exception
class and adds several useful properties for creating rich, informative error responses.
Features
- Structured Error Responses: Automatically generates a JSON response with fields like
id
,status
,code
,message
,help
,metadata
, andsource
. - Automatic Logging: It integrates with the AdonisJS logger, automatically logging 4xx errors as warnings and 5xx errors as errors.
- Customizable: You can set a custom status, error code, and add user-safe
metadata
or internalreason
details.
Usage
import { HTTPException } from "@localspace/node-lib/exception";
// Throw a generic exception
throw new HTTPException("Something went wrong", {
status: 500,
code: "E_CUSTOM_ERROR",
});
// Throw an exception with metadata for the client
throw new HTTPException("Invalid input", {
status: 400,
metadata: [{ field: "username", message: "Username is already taken" }],
});
Prop
Type
Pre-defined Exception Classes
The library includes a comprehensive list of pre-defined exception classes that extend HTTPException
, covering most standard HTTP status codes. This makes your code more readable and declarative.
Examples
Using pre-defined exceptions makes your code more semantic and easier to read.
import {
NotFoundException,
ForbiddenException,
BadRequestException,
} from "@localspace/node-lib/exception";
import User from "#models/user";
// Example 1: Handling a resource that doesn't exist.
const user = await User.find(id);
if (!user) {
throw new NotFoundException("User not found");
}
// Example 2: Checking permissions before an action.
if (await user.cannot("delete", post)) {
throw new ForbiddenException("You are not allowed to delete this post.");
}
// Example 3: Handling invalid input with more context.
const existingUser = await User.findBy("email", email);
if (existingUser) {
// The `source` can be used by the frontend to highlight the correct field.
// The `reason` is for internal logging and won't be sent to the client.
throw new BadRequestException("Invalid email or password.", {
source: "email",
reason: "User not found with the given email.",
});
}
parseError
The parseError
function is a utility to convert different types of errors into a standardized HTTPException
. This is extremely useful in your global exception handler.
Supported Error Types
HTTPException
: Returns the exception as-is.- VineJS
E_VALIDATION_ERROR
: Converts it to anUnprocessableEntityException
and puts the validation messages in themetadata
field. - AdonisJS
Exception
: Converts it to a genericHTTPException
, preserving the original status and code. SyntaxError
: Converts it to anInternalServerErrorException
.- Any other
unknown
error: Converts it to a genericInternalServerErrorException
.
Usage
In your global exception handler (app/exceptions/handler.ts
):
// app/exceptions/handler.ts
import { HttpContext, ExceptionHandler } from "@adonisjs/core/http";
import { parseError } from "@localspace/node-lib/exception";
export default class HttpExceptionHandler extends ExceptionHandler {
async handle(error: unknown, ctx: HttpContext) {
// The magic happens here!
return super.handle(parseError(error), ctx);
}
async report(error: unknown, ctx: HttpContext) {
return super.report(parseError(error), ctx);
}
}
DBReference
The DBReference class is a powerful utility for creating a type-safe and centralized reference to your database schema. It allows you to define your tables and columns in one place and then access them throughout your application with full autocompletion and type-checking.
ScopedCache
The `ScopedCache` is a powerful, type-safe, and hierarchical cache manager built on top of the AdonisJS cache provider. It simplifies working with namespaced keys, making it easy to create, manage, and invalidate related cached data.