CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-source-map-explorer

Analyze and debug space usage through source maps

Pending
Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error system with specific error codes for different failure scenarios and validation issues.

Capabilities

AppError Class

Custom error class for application-specific errors with error codes and cause tracking.

class AppError extends Error {
  /** Error code identifier */
  code?: ErrorCode;
  /** Original error that caused this error */
  cause?: Error;
  
  constructor(errorContext: ErrorContext, error?: NodeJS.ErrnoException);
}

type ErrorCode = 
  | 'Unknown'
  | 'NoBundles'
  | 'NoSourceMap'
  | 'OneSourceSourceMap'
  | 'UnmappedBytes'
  | 'InvalidMappingLine'
  | 'InvalidMappingColumn'
  | 'CannotSaveFile'
  | 'CannotCreateTempFile'
  | 'CannotOpenTempFile'
  | 'CannotOpenCoverageFile'
  | 'NoCoverageMatches';

Usage Examples:

import { explore } from "source-map-explorer";

try {
  const result = await explore("bundle.js");
} catch (error) {
  // Error handling - note that AppError is not exported from main library
  console.error(`Error: ${error.message}`);
  if (error.code) {
    console.error(`Error code: ${error.code}`);
  }
  if (error.cause) {
    console.error("Caused by:", error.cause.message);
  }
}

Error Message Details

Error messages are generated internally by the library and provide detailed context about failures. The library uses a consistent error message format that includes specific details based on the error type.

Error Code Categories

Input Validation Errors

Errors related to invalid or missing input data.

type InputErrorCode = 
  | 'NoBundles'        // No bundles provided for analysis
  | 'NoSourceMap';     // Source map not found or invalid

NoBundles Error:

  • Occurs when empty array or no files provided to explore()
  • Indicates no valid bundles to analyze
  • Usually a programming error in calling code

NoSourceMap Error:

  • Source map file not found at expected location
  • Inline source map is malformed or missing
  • Source map comment points to non-existent file

Usage Examples:

try {
  // This will throw NoBundles error
  const result = await explore([]);
} catch (error) {
  if (error instanceof AppError && error.code === 'NoBundles') {
    console.error("No bundles provided for analysis");
  }
}

try {
  // This might throw NoSourceMap error
  const result = await explore("bundle-without-sourcemap.js");
} catch (error) {
  if (error instanceof AppError && error.code === 'NoSourceMap') {
    console.error("Source map not found - make sure bundle includes source map");
  }
}

Source Map Validation Errors

Errors related to invalid or problematic source map data.

type ValidationErrorCode = 
  | 'OneSourceSourceMap'    // Source map contains only one source file
  | 'InvalidMappingLine'    // Mapping references invalid line number
  | 'InvalidMappingColumn'; // Mapping references invalid column number

OneSourceSourceMap Warning:

  • Source map contains only one source file (when analyzing single bundle)
  • Results in less useful visualization since there's no breakdown
  • This is a warning, not a fatal error

Invalid Mapping Errors:

  • Source map contains mappings pointing beyond file boundaries
  • Can be disabled with noBorderChecks: true option
  • Usually indicates source map generation issues

Usage Examples:

import { explore } from "source-map-explorer";

const result = await explore("single-file-bundle.js");

// Check for warnings
const warnings = result.errors.filter(e => e.isWarning);
warnings.forEach(warning => {
  if (warning.code === 'OneSourceSourceMap') {
    console.warn("Bundle maps to only one source file - consider analyzing multiple bundles");
  }
});

// Handle validation errors with relaxed checking
try {
  const result = await explore("problematic-bundle.js", {
    noBorderChecks: true  // Disable strict validation
  });
} catch (error) {
  if (error instanceof AppError && 
      (error.code === 'InvalidMappingLine' || error.code === 'InvalidMappingColumn')) {
    console.error("Source map has invalid mappings - try noBorderChecks: true");
  }
}

File System Errors

Errors related to file operations and I/O.

type FileSystemErrorCode = 
  | 'CannotSaveFile'        // Unable to save output file
  | 'CannotCreateTempFile'  // Unable to create temporary file
  | 'CannotOpenTempFile';   // Unable to open temporary file in browser

File Save Errors:

  • Permission issues when writing output files
  • Disk space or filesystem limitations
  • Invalid file paths or directories

Temporary File Errors:

  • Used when opening HTML visualization in browser
  • System temporary directory access issues
  • Browser launch failures

Usage Examples:

try {
  const result = await explore("bundle.js", {
    output: { format: "html", filename: "/read-only/analysis.html" }
  });
} catch (error) {
  if (error instanceof AppError && error.code === 'CannotSaveFile') {
    console.error("Cannot save output file - check permissions and disk space");
  }
}

Coverage Integration Errors

Errors related to Chrome DevTools coverage data integration.

type CoverageErrorCode = 
  | 'CannotOpenCoverageFile'  // Coverage file not found or unreadable
  | 'NoCoverageMatches';      // No coverage data matches bundle files

Coverage File Errors:

  • Coverage JSON file doesn't exist or is unreadable
  • Invalid JSON format in coverage file
  • Permission issues accessing coverage file

Coverage Matching Errors:

  • Coverage data URLs don't match bundle source files
  • Different path formats between coverage and source map
  • No overlap between coverage and bundle data

Usage Examples:

try {
  const result = await explore("bundle.js", {
    coverage: "non-existent-coverage.json"
  });
} catch (error) {
  if (error instanceof AppError && error.code === 'CannotOpenCoverageFile') {
    console.error("Coverage file not found - check path and permissions");
  }
}

// Handle coverage matching issues
const result = await explore("bundle.js", {
  coverage: "coverage.json"
});

const coverageErrors = result.errors.filter(e => e.code === 'NoCoverageMatches');
if (coverageErrors.length > 0) {
  console.warn("Coverage data doesn't match bundle files - check URL patterns");
}

Result-Level Error Handling

Analysis can partially succeed with some bundles failing. Errors are collected in the result object:

const result = await explore(["good-bundle.js", "bad-bundle.js"]);

// Check for partial failures
if (result.bundles.length > 0 && result.errors.length > 0) {
  console.log(`Analyzed ${result.bundles.length} bundles successfully`);
  console.log(`${result.errors.length} bundles failed`);
  
  // Process successful results
  result.bundles.forEach(bundle => {
    console.log(`${bundle.bundleName}: ${bundle.totalBytes} bytes`);
  });
  
  // Handle failed bundles
  result.errors.forEach(error => {
    console.error(`Failed to analyze ${error.bundleName}: ${error.message}`);
  });
}

// Check for complete failure
if (result.bundles.length === 0) {
  console.error("All bundles failed to analyze");
  throw new Error("Analysis failed completely");
}

Error Recovery Strategies

Relaxed Validation

For problematic source maps, disable strict validation:

const result = await explore("problematic-bundle.js", {
  noBorderChecks: true  // Skip mapping boundary validation
});

Alternative Input Formats

Try different input approaches if one fails:

async function analyzeWithFallback(bundlePath: string) {
  try {
    // Try with automatic source map detection
    return await explore(bundlePath);
  } catch (error) {
    if (error instanceof AppError && error.code === 'NoSourceMap') {
      try {
        // Try with explicit source map
        return await explore({
          code: bundlePath,
          map: bundlePath + '.map'
        });
      } catch (secondError) {
        // Try inline source map only
        return await explore(bundlePath, { excludeSourceMapComment: false });
      }
    }
    throw error;
  }
}

Coverage Data Handling

Graceful handling of coverage integration issues:

async function analyzeWithOptionalCoverage(bundlePath: string, coveragePath?: string) {
  const baseOptions = {
    output: { format: "html" as const }
  };
  
  if (coveragePath) {
    try {
      return await explore(bundlePath, {
        ...baseOptions,
        coverage: coveragePath
      });
    } catch (error) {
      if (error instanceof AppError && 
          (error.code === 'CannotOpenCoverageFile' || error.code === 'NoCoverageMatches')) {
        console.warn("Coverage integration failed, continuing without coverage data");
        return await explore(bundlePath, baseOptions);
      }
      throw error;
    }
  }
  
  return await explore(bundlePath, baseOptions);
}

Install with Tessl CLI

npx tessl i tessl/npm-source-map-explorer

docs

analysis-results.md

bundle-analysis.md

configuration.md

error-handling.md

index.md

tile.json