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

data-utilities.mddocs/

Data Utilities

Safe data serialization utilities with error handling for JSON conversion operations, providing robust string representation of JavaScript values.

Capabilities

Stringify

Converts a JavaScript value to a JSON string with protection against thrown errors, providing safe serialization for any value including circular references.

/**
 * Converts a JavaScript value to a JavaScript Object Notation (JSON) string with protection against thrown errors
 * @param value - A JavaScript value, usually an object or array, to be converted
 * @param replacer - The JSON.stringify() replacer argument
 * @param space - Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read
 * @returns The JSON string. If the operation fails, an error string value is returned (no exception thrown)
 */
function stringify(value: any, replacer?: any, space?: string | number): string;

Usage Examples:

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

// Basic object stringification
const simpleObj = { name: 'Alice', age: 30, active: true };
const jsonString = stringify(simpleObj);
// Result: '{"name":"Alice","age":30,"active":true}'

// Pretty printing with indentation
const prettyJson = stringify(simpleObj, null, 2);
/* Result:
{
  "name": "Alice",
  "age": 30,
  "active": true
}
*/

// Safe circular reference handling
const circularObj: any = { name: 'test' };
circularObj.self = circularObj; // Create circular reference

const safeCircular = stringify(circularObj);
// Result: '[Cannot display object: Converting circular structure to JSON]'
// No exception thrown, unlike JSON.stringify()

// Complex nested objects
const complexObj = {
  users: [
    { id: 1, name: 'Alice', metadata: { active: true, roles: ['admin', 'user'] } },
    { id: 2, name: 'Bob', metadata: { active: false, roles: ['user'] } }
  ],
  config: {
    timeout: 5000,
    retries: 3,
    endpoints: ['api.example.com', 'backup.example.com']
  }
};

const complexJson = stringify(complexObj, null, 2);
// Safely converts entire complex structure

// Custom replacer function
const objWithSensitiveData = {
  username: 'alice',
  password: 'secret123',
  email: 'alice@example.com',
  profile: { age: 30, city: 'New York' }
};

const safeReplacer = (key: string, value: any) => {
  if (key === 'password') return '[REDACTED]';
  return value;
};

const redactedJson = stringify(objWithSensitiveData, safeReplacer, 2);
// Result includes password as '[REDACTED]'

// Array replacer for key filtering
const arrayReplacer = ['username', 'email', 'profile'];
const filteredJson = stringify(objWithSensitiveData, arrayReplacer, 2);
// Only includes specified keys

// Error object stringification
const error = new Error('Something went wrong');
error.code = 'ERR_CUSTOM';
error.details = { step: 'validation', field: 'email' };

const errorJson = stringify(error);
// Safely converts error object (JSON.stringify would lose most properties)

// Date and special value handling
const specialValues = {
  now: new Date(),
  undefined: undefined,
  null: null,
  infinity: Infinity,
  nan: NaN,
  bigint: 123n
};

const specialJson = stringify(specialValues, null, 2);
// Handles all special JavaScript values safely

// Function and symbol handling
const objWithFunctions = {
  data: 'value',
  method: function() { return 'result'; },
  symbol: Symbol('test'),
  arrow: () => 'arrow result'
};

const funcJson = stringify(objWithFunctions);
// Functions and symbols are handled according to JSON.stringify rules

// Safe logging utility
function safeLog(label: string, value: any) {
  console.log(`${label}:`, stringify(value, null, 2));
}

// Usage in error handling
try {
  riskyOperation();
} catch (error) {
  console.error('Operation failed:', stringify(error));
  // Safe even if error object has circular references or other issues
}

// API response debugging
async function debugAPIResponse(url: string) {
  try {
    const response = await fetch(url);
    const data = await response.json();
    
    console.log('Response data:', stringify(data, null, 2));
    return data;
  } catch (error) {
    console.error('API Error:', stringify({
      url,
      error: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString()
    }, null, 2));
    throw error;
  }
}

// Configuration serialization
function serializeConfig(config: any): string {
  return stringify(config, (key, value) => {
    // Redact sensitive configuration values
    if (key.toLowerCase().includes('password') || 
        key.toLowerCase().includes('secret') ||
        key.toLowerCase().includes('token')) {
      return '[REDACTED]';
    }
    return value;
  }, 2);
}

// Safe state serialization for debugging
class StatefulComponent {
  private state: any;
  
  getStateSnapshot(): string {
    return stringify(this.state, null, 2);
  }
  
  debugState(): void {
    console.log('Current state:', this.getStateSnapshot());
  }
}

// Large object handling
function handleLargeObject(largeObj: any) {
  try {
    // Try normal JSON.stringify first for performance
    return JSON.stringify(largeObj);
  } catch (error) {
    // Fall back to safe stringify
    console.warn('Large object has issues, using safe stringify');
    return stringify(largeObj);
  }
}

// Custom space formatting
const customSpaceObj = { a: 1, b: { c: 2, d: 3 } };

// Using string space
const tabFormatted = stringify(customSpaceObj, null, '\t');

// Using number space
const fourSpaceFormatted = stringify(customSpaceObj, null, 4);

// No formatting
const minified = stringify(customSpaceObj);

// Testing and development utilities
function createTestSnapshot(testData: any): string {
  return stringify(testData, (key, value) => {
    // Normalize timestamps for consistent testing
    if (key.includes('timestamp') || key.includes('time')) {
      return '[TIMESTAMP]';
    }
    // Normalize IDs
    if (key === 'id' && typeof value === 'string') {
      return '[ID]';
    }
    return value;
  }, 2);
}

Important Notes:

  • stringify never throws exceptions, unlike JSON.stringify() which can throw on circular references
  • When JSON conversion fails, it returns a descriptive error string instead of throwing
  • Supports all the same parameters as JSON.stringify(): value, replacer, and space
  • Perfect for logging, debugging, and error handling where safety is more important than performance
  • Handles circular references, functions, symbols, and other problematic values gracefully
  • The error message format is: '[Cannot display object: <error description>]'
  • More robust than JSON.stringify() for untrusted or complex data structures
  • Ideal for development tools, debugging utilities, and error reporting systems