Comprehensive error classes and reporting system for validation failures and missing environment variables. Envalid provides detailed error information and customizable reporting mechanisms.
Custom error types for different validation failure scenarios.
/**
* Thrown for invalid environment variable values
* Used when validation fails due to wrong format or constraints
*/
class EnvError extends TypeError {
constructor(message?: string);
}
/**
* Thrown for missing required environment variables
* Used when required variables are not provided
*/
class EnvMissingError extends ReferenceError {
constructor(message?: string);
}Usage Examples:
import { cleanEnv, str, EnvError, EnvMissingError } from "envalid";
try {
const env = cleanEnv(process.env, {
REQUIRED_VAR: str(),
PORT: str({ choices: ["3000", "8080"] }),
});
} catch (error) {
if (error instanceof EnvMissingError) {
console.error("Missing required environment variable:", error.message);
} else if (error instanceof EnvError) {
console.error("Invalid environment variable value:", error.message);
}
}Built-in error reporter with console output and process termination in Node.js environments.
/**
* Default error reporter with console output
* Exits process with code 1 in Node.js environment
* Supports custom logger and onError callbacks
* @param opts - Reporter options containing errors and environment
* @param extraOpts - Additional options for customization
*/
function defaultReporter<T>(
opts: ReporterOptions<T>,
extraOpts?: ExtraOptions<T>
): void;Usage Examples:
import { cleanEnv, str, defaultReporter } from "envalid";
// Use default reporter with custom options
const env = cleanEnv(process.env, {
DATABASE_URL: str(),
API_KEY: str(),
}, {
reporter: (opts) => defaultReporter(opts, {
logger: console.error,
onError: (errors) => {
// Custom error handling before exit
console.log("Logging errors to monitoring service...", errors);
}
})
});Create custom error reporting logic for different environments and use cases.
interface ReporterOptions<T> {
/** Validation errors keyed by environment variable name */
errors: Partial<Record<keyof T, Error>>;
/** Raw environment object that was validated */
env: unknown;
}
interface ExtraOptions<T> {
/** Custom logger function for error output */
logger: (output: string) => void;
/** Callback executed with validation errors before exit */
onError?: (errors: Errors<T>) => void;
}Usage Examples:
import { cleanEnv, str, num } from "envalid";
// Custom reporter that logs to external service
const customReporter = ({ errors, env }) => {
const errorList = Object.entries(errors).map(([key, error]) => ({
variable: key,
message: error.message,
type: error.constructor.name
}));
// Log to external monitoring service
console.error("Environment validation failed:", {
errors: errorList,
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV
});
// Don't exit process in development
if (process.env.NODE_ENV !== "development") {
process.exit(1);
}
};
const env = cleanEnv(process.env, {
DATABASE_URL: str(),
PORT: num({ default: 3000 }),
}, {
reporter: customReporter
});Utility function for formatting validation errors with detailed output.
/**
* Formats validation errors for display
* Separates missing vs invalid variables
* Applies ANSI colors in Node.js environment
* @param errors - Collection of validation errors
* @param logger - Optional custom logger function
*/
function envalidErrorFormatter<T>(
errors: Errors<T>,
logger?: (data: any, ...args: any[]) => void
): void;
type Errors<T> = Partial<Record<keyof T, Error>>;Usage Examples:
import { cleanEnv, str, envalidErrorFormatter } from "envalid";
// Custom reporter using error formatter
const formattedReporter = ({ errors }) => {
console.log("🚨 Environment Validation Failed:");
envalidErrorFormatter(errors, (output) => {
console.error(output);
});
};
const env = cleanEnv(process.env, {
DATABASE_URL: str(),
API_KEY: str({ desc: "Secret API key for external service" }),
}, {
reporter: formattedReporter
});Disable automatic error reporting for custom error handling.
import { cleanEnv, str, EnvError, EnvMissingError } from "envalid";
// Disable reporter to handle errors manually
try {
const env = cleanEnv(process.env, {
DATABASE_URL: str(),
PORT: str({ choices: ["3000", "8080"] }),
}, {
reporter: null // Disable automatic reporting
});
} catch (error) {
// Handle errors manually
if (error instanceof EnvMissingError) {
console.log("Please set missing environment variables");
// Show user-friendly setup instructions
} else if (error instanceof EnvError) {
console.log("Please check environment variable values");
// Show configuration help
}
// Custom recovery logic
process.exit(1);
}import { cleanEnv, str, num, bool } from "envalid";
// Graceful handling with fallbacks
const getConfig = () => {
try {
return cleanEnv(process.env, {
DATABASE_URL: str(),
REDIS_URL: str(),
ENABLE_CACHE: bool({ default: true }),
});
} catch (error) {
console.warn("Using fallback configuration:", error.message);
return {
DATABASE_URL: "sqlite://./fallback.db",
REDIS_URL: "redis://localhost:6379",
ENABLE_CACHE: false,
isDevelopment: process.env.NODE_ENV === "development",
isProduction: process.env.NODE_ENV === "production",
isTest: process.env.NODE_ENV === "test",
};
}
};import { cleanEnv, str, port } from "envalid";
const getEnvironmentConfig = () => {
const reporter = process.env.NODE_ENV === "test"
? null // Silence errors in tests
: undefined; // Use default reporter
return cleanEnv(process.env, {
DATABASE_URL: str(),
PORT: port({ default: 3000 }),
}, { reporter });
};type Errors<T> = Partial<Record<keyof T, Error>>;
interface ReporterOptions<T> {
errors: Errors<T>;
env: unknown;
}
interface ExtraOptions<T> {
logger: (output: string) => void;
onError?: (errors: Errors<T>) => void;
}