Errors
Type-safe error classes for domain-specific failure modes. All errors are created using the `error-factory` pattern for consistency and type safety.
Domain Errors (domain/errors/)
Type-safe error classes for domain-specific failure modes. All errors are created using the error-factory pattern for consistency and type safety.
Error Classes
validation-error.ts
Input validation failures (bad user input, constraint violations).
throw new ValidationError("Municipality name cannot be empty");
throw new ValidationError("Invalid format", { field: "zipCode", value: "abc" });
address-not-found.ts
Address geocoding returned no results or low-confidence matches.
throw new AddressNotFoundError({ address: "999 Fake St, Newark, NJ" });
api-timeout.ts
External API request exceeded timeout threshold.
throw new ApiTimeoutError({ url: "https://geo.nj.gov/...", timeoutMs: 10000 });
invalid-api-response.ts
External API returned malformed or unexpected data structure.
throw new InvalidApiResponseError({ message: "Missing candidates array", url });
cache-error.ts
Cache operations failed (read/write/eviction errors).
throw new CacheError("Failed to evict entries", { attemptedCount: 10 });
invalid-address.ts
Address failed security validation (XSS patterns, SQL injection attempts).
throw new InvalidAddressError("Address contains dangerous patterns", {
pattern: "<script>",
});
Error Factory Pattern
All errors use the generic createCustomError factory:
export const ValidationError = createCustomError<
"ValidationError",
Record<string, unknown>
>({
name: "ValidationError",
});
Benefits:
- Consistent structure across all errors
- Type-safe data payloads
- Automatic serialization (toJSON)
- Stack traces preserved
- Eliminates boilerplate
Usage Patterns
Throwing Errors
// Simple message
throw new ValidationError("Invalid input");
// With structured data
throw new ApiTimeoutError({
url: "https://api.example.com",
timeoutMs: 5000,
attempt: 3,
});
Catching Errors
try {
const result = await geocode(address);
} catch (error) {
if (error instanceof AddressNotFoundError) {
// Handle specific error type
console.log(`Address not found: ${error.data.address}`);
} else if (error instanceof ApiTimeoutError) {
console.log(`Timeout after ${error.data.timeoutMs}ms`);
}
throw error;
}
Serialization
All errors serialize cleanly for logging and API responses:
const error = new ValidationError("Bad input", { field: "email" });
console.log(JSON.stringify(error)); // { name, message, data, stack }
Testing
Each error has unit tests verifying:
- Correct error name and instanceof checks
- Message formatting with data
- Data payload structure
- JSON serialization
- Stack trace preservation
Entities
Core business objects representing key concepts in the application domain. All entities are immutable and validated upon creation.
Ports
Interface definitions for external dependencies following the Ports & Adapters (Hexagonal) architecture pattern. The domain defines contracts; adapters implemen