Error
Standardized error class and factory for throwing HTTP-aware errors with machine-readable codes across the application.
Quick Reference
| Item | Value |
|---|---|
| Package | @venizia/ignis-helpers |
| Class | ApplicationError |
| Extends | Error (native) |
| Runtimes | Both |
Import Paths
import { ApplicationError, getError } from '@venizia/ignis-helpers';
import { ErrorSchema } from '@venizia/ignis-helpers';
import type { TError } from '@venizia/ignis-helpers';Creating an Instance
ApplicationError extends the native Error class with an HTTP statusCode and an optional messageCode for machine-readable error identification.
import { ApplicationError, HTTP } from '@venizia/ignis-helpers';
const error = new ApplicationError({
message: 'User not found',
statusCode: HTTP.ResultCodes.RS_4.NotFound,
messageCode: 'USER_NOT_FOUND',
});Constructor Options (TError)
| Option | Type | Default | Description |
|---|---|---|---|
message | string | -- (required) | Human-readable error message |
statusCode | number | 400 | HTTP status code |
messageCode | string | undefined | Machine-readable error code for client-side handling |
name | string | undefined | Error name |
TIP
The TError type is derived from ErrorSchema (a Zod schema) and uses .catchall(z.any()), so you can pass additional arbitrary properties beyond the four listed above.
getError() Factory Function
For convenience, use the standalone getError() function instead of calling new ApplicationError() directly. This is the preferred pattern throughout the Ignis codebase.
import { getError, HTTP } from '@venizia/ignis-helpers';
throw getError({
message: 'Invalid credentials',
statusCode: HTTP.ResultCodes.RS_4.Unauthorized,
messageCode: 'INVALID_CREDENTIALS',
});ApplicationError.getError() Static Method
An equivalent static factory method on the class itself:
throw ApplicationError.getError({
message: 'Configuration missing',
statusCode: HTTP.ResultCodes.RS_5.InternalServerError,
});Usage
Throwing Errors in Services
The most common pattern is throwing ApplicationError from service methods to signal HTTP-level failures. The framework's error handling middleware catches these and formats the response automatically.
import { getError, HTTP } from '@venizia/ignis-helpers';
class AuthenticationService {
async signUp(opts: { username: string; credential: string }) {
const existingUser = await this.userRepository.findByUsername(opts.username);
if (existingUser) {
throw getError({
statusCode: HTTP.ResultCodes.RS_4.Conflict,
message: 'Username already exists',
});
}
// ...
}
}Using messageCode for Client-Side Handling
The messageCode field allows frontend applications to map errors to localized messages or specific UI behaviors without parsing the human-readable message string.
throw getError({
message: 'Email verification required before login',
statusCode: HTTP.ResultCodes.RS_4.Forbidden,
messageCode: 'auth.email_not_verified',
});Error Response Format
The built-in appErrorHandler middleware (from @venizia/ignis) catches ApplicationError instances and formats them into consistent JSON responses. The response shape differs by environment.
Production Response
{
"message": "User not found",
"statusCode": 404,
"requestId": "abc-123-def"
}Development Response
In development (NODE_ENV=development), additional debugging fields are included:
{
"message": "User not found",
"statusCode": 404,
"requestId": "abc-123-def",
"details": {
"url": "http://localhost:3000/api/users/123",
"path": "/api/users/123",
"stack": "Error: User not found\n at ...",
"cause": "..."
}
}ErrorSchema (Zod)
ErrorSchema is a Zod object schema used for OpenAPI response documentation. It is typically referenced in route definitions to describe error responses.
import { ErrorSchema, HTTP } from '@venizia/ignis-helpers';
// In route definition responses
const responses = {
[HTTP.ResultCodes.RS_4.NotFound]: {
description: 'Resource not found',
content: {
'application/json': { schema: ErrorSchema },
},
},
};The schema shape:
const ErrorSchema = z
.object({
name: z.string().optional(),
statusCode: z.number().optional(),
messageCode: z.string().optional(),
message: z.string(),
})
.catchall(z.any());Common Status Code Patterns
| Scenario | Status Code | HTTP.ResultCodes Path |
|---|---|---|
| Invalid input / bad request | 400 | RS_4.BadRequest |
| Missing or invalid auth | 401 | RS_4.Unauthorized |
| Insufficient permissions | 403 | RS_4.Forbidden |
| Resource not found | 404 | RS_4.NotFound |
| Duplicate resource | 409 | RS_4.Conflict |
| Validation error | 422 | RS_4.UnprocessableEntity |
| Server failure | 500 | RS_5.InternalServerError |
Troubleshooting
statusCode defaults to 400
Cause: getError() was called without specifying a statusCode. The ApplicationError constructor defaults to 400 (Bad Request).
Fix: Always provide an explicit status code using HTTP.ResultCodes:
throw getError({
message: 'Resource not found',
statusCode: HTTP.ResultCodes.RS_4.NotFound,
});Error response missing stack and cause
Cause: The application is running in production mode. The appErrorHandler middleware strips stack, cause, url, and path from responses when NODE_ENV is not development.
Fix: Set NODE_ENV=development to see full error details during debugging.
Errors returning 500 instead of expected status code
Cause: A plain Error (not ApplicationError) was thrown. The appErrorHandler middleware only reads statusCode from errors that have that property. Native Error instances default to 500.
Fix: Use getError() or new ApplicationError() instead of new Error():
// Incorrect -- will return 500
throw new Error('Not found');
// Correct -- will return 404
throw getError({
message: 'Not found',
statusCode: HTTP.ResultCodes.RS_4.NotFound,
});See Also
- Controllers -- Throwing errors in route handlers
- Services -- Error handling in business logic
- Middlewares -- The
appErrorHandlermiddleware - Helpers Index -- All available helpers
- Logger Helper -- Logging errors