or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdasync-promise-utilities.mddata-utilities.mdfunction-utilities.mdindex.mdobject-operations.mdpath-operations.mdperformance-benchmarking.mdstring-utilities.mdvalidation-assertions.md
tile.json

validation-assertions.mddocs/

Validation and Assertions

Lightweight assertion utilities with custom error types for runtime validation and error handling in Node.js applications.

Capabilities

Assert

Throws an error if condition is falsy, providing flexible error message construction and TypeScript assertion support.

/**
 * Throw an error if condition is falsy
 * @param condition - If condition is not truthy, an exception is thrown
 * @param error - The error thrown if the condition fails
 * @returns Does not return a value but throws if the condition is falsy
 */
function assert(condition: any, error: Error): asserts condition;

/**
 * Throw an error if condition is falsy
 * @param condition - If condition is not truthy, an exception is thrown  
 * @param args - Any number of values, concatenated together (space separated) to create the error message
 * @returns Does not return a value but throws if the condition is falsy
 */
function assert(condition: any, ...args: any): asserts condition;

Usage Examples:

import { assert } from "@hapi/hoek";

// Basic assertion with string message
const value = 42;
assert(value > 0, 'Value must be positive');

// Multiple arguments concatenated
const user = { name: 'Alice', age: 25 };
assert(user.age >= 18, 'User', user.name, 'must be at least 18 years old');
// Throws: 'User Alice must be at least 18 years old'

// Using with pre-created Error object
const customError = new TypeError('Expected number, got string');
assert(typeof value === 'number', customError);

// TypeScript assertion benefits
function processUser(user: any) {
  assert(user && typeof user === 'object', 'User must be an object');
  assert(typeof user.name === 'string', 'User name must be a string');
  // TypeScript now knows user.name is a string
  return user.name.toUpperCase();
}

// Complex validation
function validateConfig(config: any) {
  assert(config, 'Configuration is required');
  assert(config.host, 'Host configuration is required');
  assert(typeof config.port === 'number', 'Port must be a number');
  assert(config.port > 0 && config.port < 65536, 'Port must be between 1 and 65535');
}

// Error object passthrough
const validationError = new Error('Custom validation failed');
validationError.code = 'VALIDATION_ERROR';
assert(false, validationError); // Throws the exact error object

// Filtering empty strings from error messages
assert(false, 'Error:', '', 'something went wrong');
// Throws: 'Error: something went wrong' (empty string filtered out)

// Mixed data types in error message
const count = 5;
const items = ['a', 'b', 'c'];
assert(items.length >= count, 'Expected at least', count, 'items, got', items.length);
// Throws: 'Expected at least 5 items, got 3'

AssertError

Custom error class thrown by the assert function with clean stack traces and consistent error handling.

/**
 * Assertion Error as thrown from Hoek.assert()
 */
class AssertError extends Error {
  name: 'AssertError';
}

Usage Examples:

import { assert, AssertError } from "@hapi/hoek";

// Catching assertion errors specifically
try {
  assert(false, 'This will fail');
} catch (error) {
  if (error instanceof AssertError) {
    console.log('Assertion failed:', error.message);
    console.log('Error name:', error.name); // 'AssertError'
  }
}

// Error handling in async functions
async function validateAndProcess(data: any) {
  try {
    assert(data, 'Data is required');
    assert(Array.isArray(data.items), 'Items must be an array');
    
    return data.items.map(processItem);
  } catch (error) {
    if (error instanceof AssertError) {
      throw new Error(`Validation failed: ${error.message}`);
    }
    throw error; // Re-throw non-assertion errors
  }
}

// Custom error handling with context
function safeAssert(condition: any, message: string, context?: any) {
  try {
    assert(condition, message);
  } catch (error) {
    if (error instanceof AssertError && context) {
      error.context = context;
    }
    throw error;
  }
}

// Using in middleware or validation layers
function validateRequest(req: any, res: any, next: any) {
  try {
    assert(req.body, 'Request body is required');
    assert(req.body.email, 'Email is required');
    assert(typeof req.body.email === 'string', 'Email must be a string');
    next();
  } catch (error) {
    if (error instanceof AssertError) {
      res.status(400).json({ error: error.message });
    } else {
      next(error);
    }
  }
}

// Stack trace cleanup
// AssertError automatically cleans up stack traces to point to the assertion location
// rather than internal assert() implementation details

Important Notes:

  • assert provides TypeScript assertion type guards, allowing the compiler to narrow types after successful assertions
  • The function accepts either a pre-constructed Error object or message components that are concatenated
  • Empty strings in message arguments are automatically filtered out
  • AssertError includes automatic stack trace cleanup for cleaner debugging
  • Both functions are lightweight with minimal performance overhead
  • Perfect for input validation, precondition checking, and development-time assertions
  • Works seamlessly with async/await patterns and Promise-based code