CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-xmldom--xmldom

A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module

Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error reporting system with DOM-standard exceptions and parsing-specific error types for robust XML processing applications.

Capabilities

DOMException Class

Standard DOM exception class for DOM manipulation errors.

/**
 * DOM-specific exception class following W3C standards
 * Thrown by DOM operations that encounter exceptional conditions
 */
class DOMException extends Error {
  constructor(message?: string, name?: string);
  constructor(code?: number, message?: string);
  
  readonly name: string; // Exception name
  readonly code: number; // Numeric exception code (0 for modern names)
  
  // Static exception codes (legacy)
  static readonly INDEX_SIZE_ERR: 1;
  static readonly DOMSTRING_SIZE_ERR: 2;
  static readonly HIERARCHY_REQUEST_ERR: 3;
  static readonly WRONG_DOCUMENT_ERR: 4;
  static readonly INVALID_CHARACTER_ERR: 5;
  static readonly NO_DATA_ALLOWED_ERR: 6;
  static readonly NO_MODIFICATION_ALLOWED_ERR: 7;
  static readonly NOT_FOUND_ERR: 8;
  static readonly NOT_SUPPORTED_ERR: 9;
  static readonly INUSE_ATTRIBUTE_ERR: 10;
  static readonly INVALID_STATE_ERR: 11;
  static readonly SYNTAX_ERR: 12;
  static readonly INVALID_MODIFICATION_ERR: 13;
  static readonly NAMESPACE_ERR: 14;
  static readonly INVALID_ACCESS_ERR: 15;
  static readonly VALIDATION_ERR: 16;
  static readonly TYPE_MISMATCH_ERR: 17;
  static readonly SECURITY_ERR: 18;
  static readonly NETWORK_ERR: 19;
  static readonly ABORT_ERR: 20;
  static readonly URL_MISMATCH_ERR: 21;
  static readonly QUOTA_EXCEEDED_ERR: 22;
  static readonly TIMEOUT_ERR: 23;
  static readonly INVALID_NODE_TYPE_ERR: 24;
  static readonly DATA_CLONE_ERR: 25;
}

Usage Examples:

const { DOMParser, DOMException } = require('@xmldom/xmldom');

try {
  const doc = parser.parseFromString('<root></root>', 'text/xml');
  const root = doc.documentElement;
  
  // This might throw a DOMException
  root.removeChild(doc.createElement('nonexistent'));
} catch (error) {
  if (error instanceof DOMException) {
    console.log(`DOM Error: ${error.name} (${error.code}): ${error.message}`);
    
    switch (error.name) {
      case 'NotFoundError':
        console.log('Attempted to remove non-existent child');
        break;
      case 'HierarchyRequestError':
        console.log('Invalid tree modification');
        break;
      case 'WrongDocumentError':
        console.log('Node belongs to different document');
        break;
    }
  }
}

ParseError Class

Specialized error class for XML parsing failures.

/**
 * Error thrown during XML parsing when fatal errors occur
 * Provides additional context about parse location and cause
 */
class ParseError extends Error {
  constructor(message: string, locator?: any, cause?: Error);
  
  readonly message: string;
  readonly locator?: any; // Location information if available
  readonly cause?: Error; // Underlying cause if chained
}

Usage Examples:

const { DOMParser, ParseError } = require('@xmldom/xmldom');

const parser = new DOMParser({
  onError: (level, message, context) => {
    if (level === 'fatalError') {
      throw new ParseError(`Fatal parsing error: ${message}`, context);
    }
  }
});

try {
  const doc = parser.parseFromString('<invalid><xml>', 'text/xml');
} catch (error) {
  if (error instanceof ParseError) {
    console.log(`Parse Error: ${error.message}`);
    if (error.locator) {
      console.log(`Location: line ${error.locator.lineNumber}, column ${error.locator.columnNumber}`);
    }
  }
}

Exception Names and Codes

/**
 * Standard DOM exception names
 */
const DOMExceptionName = {
  Error: 'Error',
  IndexSizeError: 'IndexSizeError', // deprecated
  DomstringSizeError: 'DomstringSizeError', // deprecated
  HierarchyRequestError: 'HierarchyRequestError',
  WrongDocumentError: 'WrongDocumentError',
  InvalidCharacterError: 'InvalidCharacterError',
  NoDataAllowedError: 'NoDataAllowedError', // deprecated
  NoModificationAllowedError: 'NoModificationAllowedError',
  NotFoundError: 'NotFoundError',
  NotSupportedError: 'NotSupportedError',
  InUseAttributeError: 'InUseAttributeError',
  InvalidStateError: 'InvalidStateError',
  SyntaxError: 'SyntaxError',
  InvalidModificationError: 'InvalidModificationError',
  NamespaceError: 'NamespaceError',
  InvalidAccessError: 'InvalidAccessError', // deprecated
  ValidationError: 'ValidationError', // deprecated
  TypeMismatchError: 'TypeMismatchError', // deprecated
  SecurityError: 'SecurityError',
  NetworkError: 'NetworkError',
  AbortError: 'AbortError',
  URLMismatchError: 'URLMismatchError', // deprecated
  QuotaExceededError: 'QuotaExceededError',
  TimeoutError: 'TimeoutError',
  InvalidNodeTypeError: 'InvalidNodeTypeError',
  DataCloneError: 'DataCloneError',
  EncodingError: 'EncodingError',
  NotReadableError: 'NotReadableError',
  UnknownError: 'UnknownError',
  ConstraintError: 'ConstraintError',
  DataError: 'DataError',
  TransactionInactiveError: 'TransactionInactiveError',
  ReadOnlyError: 'ReadOnlyError',
  VersionError: 'VersionError',
  OperationError: 'OperationError',
  NotAllowedError: 'NotAllowedError',
  OptOutError: 'OptOutError'
};

/**
 * Legacy numeric exception codes
 */
const ExceptionCode = {
  INDEX_SIZE_ERR: 1,
  DOMSTRING_SIZE_ERR: 2,
  HIERARCHY_REQUEST_ERR: 3,
  WRONG_DOCUMENT_ERR: 4,
  INVALID_CHARACTER_ERR: 5,
  NO_DATA_ALLOWED_ERR: 6,
  NO_MODIFICATION_ALLOWED_ERR: 7,
  NOT_FOUND_ERR: 8,
  NOT_SUPPORTED_ERR: 9,
  INUSE_ATTRIBUTE_ERR: 10,
  INVALID_STATE_ERR: 11,
  SYNTAX_ERR: 12,
  INVALID_MODIFICATION_ERR: 13,
  NAMESPACE_ERR: 14,
  INVALID_ACCESS_ERR: 15,
  VALIDATION_ERR: 16,
  TYPE_MISMATCH_ERR: 17,
  SECURITY_ERR: 18,
  NETWORK_ERR: 19,
  ABORT_ERR: 20,
  URL_MISMATCH_ERR: 21,
  QUOTA_EXCEEDED_ERR: 22,
  TIMEOUT_ERR: 23,
  INVALID_NODE_TYPE_ERR: 24,
  DATA_CLONE_ERR: 25
};

Common Error Scenarios

DOM Manipulation Errors:

const { DOMParser, DOMException } = require('@xmldom/xmldom');

const parser = new DOMParser();
const doc1 = parser.parseFromString('<root1></root1>', 'text/xml');
const doc2 = parser.parseFromString('<root2></root2>', 'text/xml');

try {
  // WrongDocumentError: Cannot adopt node from different document
  doc1.documentElement.appendChild(doc2.documentElement);
} catch (error) {
  console.log(error.name); // 'WrongDocumentError'
}

try {
  // HierarchyRequestError: Cannot insert node as child of itself
  const root = doc1.documentElement;
  root.appendChild(root);
} catch (error) {
  console.log(error.name); // 'HierarchyRequestError'
}

try {
  // NotFoundError: Attribute doesn't exist
  const attr = doc1.documentElement.getAttributeNode('nonexistent');
  doc1.documentElement.removeAttributeNode(attr);
} catch (error) {
  console.log(error.name); // 'NotFoundError'
}

Parsing Error Handling:

const { DOMParser, ParseError, onErrorStopParsing } = require('@xmldom/xmldom');

// Custom error handler
const parser = new DOMParser({
  onError: (level, message, context) => {
    const location = context ? `at line ${context.lineNumber}, column ${context.columnNumber}` : '';
    console.log(`${level.toUpperCase()}: ${message} ${location}`);
    
    if (level === 'fatalError') {
      throw new ParseError(message, context);
    }
  }
});

// Using predefined error handlers
const strictParser = new DOMParser({
  onError: onErrorStopParsing // Stops on any error
});

const veryStrictParser = new DOMParser({
  onError: onWarningStopParsing // Stops on warnings too
});

Error Recovery Strategies:

function parseXmlSafely(xmlString, fallbackValue = null) {
  const parser = new DOMParser({
    onError: (level, message) => {
      console.warn(`XML ${level}: ${message}`);
      // Log but continue parsing for warnings and errors
      // Only fatal errors will throw
    }
  });
  
  try {
    return parser.parseFromString(xmlString, 'text/xml');
  } catch (error) {
    if (error instanceof ParseError) {
      console.error('Failed to parse XML:', error.message);
      return fallbackValue;
    }
    throw error; // Re-throw unexpected errors
  }
}

// Usage
const doc = parseXmlSafely('<invalid><xml>', null);
if (doc === null) {
  console.log('Parsing failed, using fallback');
}

Validation and Error Prevention:

const { isValidMimeType, MIME_TYPE } = require('@xmldom/xmldom');

function safeParseFromString(xmlString, mimeType) {
  // Validate MIME type before parsing
  if (!isValidMimeType(mimeType)) {
    throw new TypeError(`Invalid MIME type: ${mimeType}`);
  }
  
  // Validate input
  if (typeof xmlString !== 'string') {
    throw new TypeError('XML source must be a string');
  }
  
  if (xmlString.trim() === '') {
    throw new Error('XML source cannot be empty');
  }
  
  const parser = new DOMParser();
  return parser.parseFromString(xmlString, mimeType);
}

// Safe usage
try {
  const doc = safeParseFromString('<root></root>', MIME_TYPE.XML_APPLICATION);
} catch (error) {
  console.error('Safe parsing failed:', error.message);
}

Error Logging and Debugging

const { DOMParser } = require('@xmldom/xmldom');

// Comprehensive error logging
const debugParser = new DOMParser({
  locator: true, // Enable location tracking
  onError: (level, message, context) => {
    const timestamp = new Date().toISOString();
    const location = context && context.lineNumber ? 
      `${context.lineNumber}:${context.columnNumber}` : 'unknown';
    
    const logEntry = {
      timestamp,
      level,
      message,
      location,
      context: context ? { ...context } : null
    };
    
    console.log('XML Parse Event:', JSON.stringify(logEntry, null, 2));
    
    // Store in application log
    if (typeof applicationLogger !== 'undefined') {
      applicationLogger.log(level, 'XML Parse Error', logEntry);
    }
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-xmldom--xmldom

docs

constants-utilities.md

dom-manipulation.md

error-handling.md

index.md

parsing.md

serialization.md

tile.json