or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bundling.mddereferencing.mderrors.mdindex.mdoptions.mdparsing.mdresolution.md
tile.json

errors.mddocs/

Error Handling

Robust error handling system with specific error types for different failure scenarios and detailed error information. The library provides comprehensive error reporting with source location, error codes, and contextual information to help diagnose and resolve issues.

Capabilities

Base Error Classes

Core error classes that all other errors inherit from.

/**
 * Base error class for all JSON Schema $Ref Parser errors
 */
class JSONParserError extends Error {
  /**
   * Error class name (always "JSONParserError")
   */
  readonly name: string;

  /**
   * Human-readable error message
   */
  readonly message: string;

  /**
   * Source file or URL where the error occurred
   */
  source: string | undefined;

  /**
   * Path within the schema where the error occurred
   */
  path: Array<string | number> | null;

  /**
   * Specific error type code
   */
  readonly code: JSONParserErrorType;

  /**
   * Creates a new JSONParserError
   * @param message - Error description
   * @param source - Source file where error occurred
   */
  constructor(message: string, source?: string);

  /**
   * Custom JSON serialization method
   * @returns Serializable representation of the error
   */
  toJSON(): Error & this;

  /**
   * Unique identifier for this error instance
   * Combines path, source, code, and message
   */
  get footprint(): string;
}

/**
 * Container for multiple parsing errors
 * Thrown when continueOnError is true and multiple errors occur
 */
class JSONParserErrorGroup<
  S extends object = JSONSchema,
  O extends ParserOptions<S> = ParserOptions<S>
> extends Error {
  /**
   * Error class name (always "JSONParserErrorGroup")
   */
  readonly name: string;

  /**
   * The parser instance containing all errors
   */
  files: $RefParser<S, O>;

  /**
   * Creates a new error group
   * @param parser - Parser instance with accumulated errors
   */
  constructor(parser: $RefParser<S, O>);

  /**
   * Gets all parser errors from the group
   * @param parser - Parser instance to extract errors from
   * @returns Array of all JSONParserError instances
   */
  static getParserErrors<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
    parser: $RefParser<S, O>
  ): JSONParserError[];
}

Specific Error Types

Specialized error classes for different types of failures.

/**
 * Error thrown when a JSON pointer is invalid
 */
class InvalidPointerError extends JSONParserError {
  readonly code: "EINVALIDPOINTER";
}

/**
 * Error thrown when a JSON pointer cannot be found
 */
class MissingPointerError extends JSONParserError {
  readonly code: "EMISSINGPOINTER";
  targetToken: any;
  targetRef: string;
  targetFound: string;
  parentPath: string;
}

/**
 * Error thrown by resolvers when they cannot read a file
 */
class ResolverError extends JSONParserError {
  readonly code: "ERESOLVER";
  ioErrorCode?: string;
}

/**
 * Error thrown by parsers when they cannot parse a file
 */
class ParserError extends JSONParserError {
  readonly code: "EPARSER";
}

/**
 * Error thrown when no suitable parser is found for a file
 */
class UnmatchedParserError extends JSONParserError {
  readonly code: "EUNMATCHEDPARSER";
}

/**
 * Error thrown when no suitable resolver is found for a URL
 */
class UnmatchedResolverError extends JSONParserError {
  readonly code: "EUNMATCHEDRESOLVER";
}

/**
 * Error thrown when an operation times out
 */
class TimeoutError extends JSONParserError {
  readonly code: "ETIMEOUT";
}

Error Type Codes

Enumeration of all possible error codes.

/**
 * All possible error type codes
 */
type JSONParserErrorType =
  | "EUNKNOWN"           // Unknown or generic error
  | "EPARSER"            // Parser-specific error
  | "EUNMATCHEDPARSER"   // No matching parser found
  | "ETIMEOUT"           // Operation timeout
  | "ERESOLVER"          // Resolver-specific error
  | "EUNMATCHEDRESOLVER" // No matching resolver found
  | "EMISSINGPOINTER"    // JSON pointer not found
  | "EINVALIDPOINTER";   // JSON pointer is invalid

Error Detection Utilities

Utilities for working with errors.

/**
 * Checks if an error is handled by the parser system
 * @param err - Error to check
 * @returns True if the error is a known parser error type
 */
function isHandledError(err: any): err is JSONParserError;

/**
 * Custom JSON serializer for Error objects
 * Returns all built-in error properties plus extended properties
 * @returns Serializable error representation
 */
function toJSON<T extends Error>(this: T): Error & T;

/**
 * Returns all object keys including inherited, non-enumerable, and symbol keys
 * Excludes base Object prototype and protected properties
 * @param obj - Object to get keys from
 * @param omit - Keys to omit from the result
 * @returns Set of all deep keys
 */
function getDeepKeys(obj: object, omit?: Array<string | symbol>): Set<string | symbol>;

Error Handling Patterns

Basic Error Handling

import $RefParser, { JSONParserError, isHandledError } from "@apidevtools/json-schema-ref-parser";

try {
  const schema = await $RefParser.dereference("./schema.json");
} catch (error) {
  if (error instanceof JSONParserError) {
    console.error("Parser Error:");
    console.error("  Message:", error.message);
    console.error("  Code:", error.code);
    console.error("  Source:", error.source);
    console.error("  Path:", error.path);
  } else {
    console.error("Unexpected error:", error);
  }
}

Specific Error Type Handling

import $RefParser, {
  ResolverError,
  ParserError,
  InvalidPointerError,
  MissingPointerError
} from "@apidevtools/json-schema-ref-parser";

try {
  const schema = await $RefParser.resolve("./schema.json");
} catch (error) {
  if (error instanceof ResolverError) {
    console.error("Could not resolve reference:", error.source);
    
    if (error.source?.startsWith("http")) {
      console.error("Network error - check URL and connectivity");
    } else {
      console.error("File error - check file path and permissions");
    }
    
  } else if (error instanceof ParserError) {
    console.error("Could not parse file:", error.source);
    console.error("Check file format and syntax");
    
  } else if (error instanceof InvalidPointerError) {
    console.error("Invalid JSON pointer:", error.path);
    
  } else if (error instanceof MissingPointerError) {
    console.error("JSON pointer not found:", error.path);
  }
}

Multiple Error Handling

import $RefParser, { JSONParserErrorGroup } from "@apidevtools/json-schema-ref-parser";

try {
  const schema = await $RefParser.dereference("./schema.json", {
    continueOnError: true  // Collect all errors instead of failing fast
  });
} catch (error) {
  if (error instanceof JSONParserErrorGroup) {
    console.error("Multiple errors encountered:");
    
    const errors = JSONParserErrorGroup.getParserErrors(error.files);
    errors.forEach((err, index) => {
      console.error(`Error ${index + 1}:`);
      console.error("  Message:", err.message);
      console.error("  Code:", err.code);
      console.error("  Source:", err.source);
      console.error("  Path:", err.path);
      console.error("  Footprint:", err.footprint);
    });
    
    // Group errors by type
    const errorsByType = errors.reduce((acc, err) => {
      acc[err.code] = acc[err.code] || [];
      acc[err.code].push(err);
      return acc;
    }, {} as Record<string, JSONParserError[]>);
    
    console.error("Error summary:", Object.keys(errorsByType).map(code => 
      `${code}: ${errorsByType[code].length}`
    ).join(", "));
  }
}

Callback Error Handling

import $RefParser from "@apidevtools/json-schema-ref-parser";

// Callback-style error handling
$RefParser.parse("./schema.json", (error, schema) => {
  if (error) {
    console.error("Parse failed:", error.message);
    
    if (error.code === "EPARSER") {
      console.error("File parsing error in:", error.source);
    } else if (error.code === "ERESOLVER") {
      console.error("File resolution error for:", error.source);
    }
    
    return;
  }
  
  console.log("Successfully parsed schema:", schema);
});

Error Information Access

import $RefParser, { JSONParserError } from "@apidevtools/json-schema-ref-parser";

try {
  const schema = await $RefParser.bundle("./schema.json");
} catch (error) {
  if (error instanceof JSONParserError) {
    // Access detailed error information
    const errorInfo = {
      type: error.name,
      code: error.code,
      message: error.message,
      source: error.source,
      path: error.path,
      footprint: error.footprint,
      
      // Get full serializable representation
      full: error.toJSON()
    };
    
    console.error("Detailed error info:", JSON.stringify(errorInfo, null, 2));
    
    // Error fingerprinting for deduplication
    const seen = new Set();
    if (!seen.has(error.footprint)) {
      seen.add(error.footprint);
      console.error("New error encountered:", error.footprint);
    }
  }
}

Custom Error Handling Utilities

import $RefParser, { JSONParserError, isHandledError } from "@apidevtools/json-schema-ref-parser";

function handleSchemaError(error: unknown): void {
  if (isHandledError(error)) {
    // This is a known parser error
    switch (error.code) {
      case "ERESOLVER":
        console.error(`Resolution failed for ${error.source}: ${error.message}`);
        break;
        
      case "EPARSER":
        console.error(`Parsing failed for ${error.source}: ${error.message}`);
        break;
        
      case "ETIMEOUT":
        console.error(`Operation timed out: ${error.message}`);
        break;
        
      case "EMISSINGPOINTER":
        console.error(`Reference not found at ${error.path}: ${error.message}`);
        break;
        
      case "EINVALIDPOINTER":
        console.error(`Invalid reference path ${error.path}: ${error.message}`);
        break;
        
      default:
        console.error(`Parser error (${error.code}): ${error.message}`);
    }
  } else {
    // Unknown error type
    console.error("Unexpected error:", error);
  }
}

// Usage
try {
  const result = await $RefParser.dereference("./schema.json");
} catch (error) {
  handleSchemaError(error);
}

Error Prevention Best Practices

Validation Before Processing

import $RefParser from "@apidevtools/json-schema-ref-parser";
import { existsSync } from "fs";

async function safeParseSchema(schemaPath: string) {
  // Pre-validate file existence for local files
  if (!schemaPath.startsWith("http") && !existsSync(schemaPath)) {
    throw new Error(`Schema file not found: ${schemaPath}`);
  }
  
  try {
    return await $RefParser.parse(schemaPath);
  } catch (error) {
    console.error(`Failed to parse schema at ${schemaPath}:`, error);
    throw error;
  }
}

Graceful Degradation

import $RefParser from "@apidevtools/json-schema-ref-parser";

async function parseSchemaWithFallback(primaryPath: string, fallbackPath: string) {
  try {
    return await $RefParser.parse(primaryPath);
  } catch (primaryError) {
    console.warn(`Primary schema failed (${primaryPath}), trying fallback...`);
    
    try {
      return await $RefParser.parse(fallbackPath);
    } catch (fallbackError) {
      throw new Error(`Both primary and fallback schemas failed:\n` +
        `Primary: ${primaryError.message}\n` +
        `Fallback: ${fallbackError.message}`);
    }
  }
}

Timeout Protection

import $RefParser from "@apidevtools/json-schema-ref-parser";

async function parseWithTimeout(schemaPath: string, timeoutMs: number = 30000) {
  try {
    return await $RefParser.parse(schemaPath, {
      timeoutMs,
      resolve: {
        http: {
          timeout: Math.min(timeoutMs / 2, 10000) // HTTP timeout should be less than total
        }
      }
    });
  } catch (error) {
    if (error.code === "ETIMEOUT") {
      throw new Error(`Schema parsing timed out after ${timeoutMs}ms`);
    }
    throw error;
  }
}