or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-engine.mdcomponents.mdcontrollers.mddata-structures.mddebugging-development.mddestroyables-cleanup.mdindex.mdmodifiers.mdobject-model.mdreactivity-tracking.mdrouting.mdservices.mdtemplates-rendering.mdtesting.mdutilities.md
tile.json

debugging-development.mddocs/

Debugging & Development

Development tools and debugging utilities for inspecting application state and troubleshooting issues.

Capabilities

Debug Functions

Core debugging functions for assertions, warnings, and development-time feedback.

/**
 * Runtime assertion that throws error if condition is false
 * @param message - Error message to display
 * @param condition - Condition that must be true
 */
function assert(message: string, condition: boolean): void;

/**
 * Display warning message in development builds
 * @param message - Warning message
 * @param condition - Condition to test (warning shown if false)
 * @param options - Additional warning options
 */
function warn(message: string, condition?: boolean, options?: WarnOptions): void;

/**
 * Log debug message (only in debug builds)
 * @param message - Debug message to log
 */
function debug(message: string): void;

/**
 * Display deprecation warning for outdated API usage
 * @param message - Deprecation message
 * @param condition - Condition to test (deprecation shown if false)
 * @param options - Deprecation options including id and until version
 */
function deprecate(message: string, condition?: boolean, options?: DeprecateOptions): void;

/**
 * Execute code only in debug builds
 * @param fn - Function to execute in debug mode
 */
function runInDebug(fn: () => void): void;

Usage Examples:

import { assert, warn, debug, deprecate, runInDebug } from "@ember/debug";

export default class UserService extends Service {
  createUser(userData) {
    // Assertions for required parameters
    assert('User data is required', userData != null);
    assert('User must have email', userData.email);
    assert('Email must be valid', userData.email.includes('@'));
    
    // Warnings for potentially problematic situations
    warn('User age not provided, defaulting to 0', userData.age != null, {
      id: 'user-service.missing-age'
    });
    
    // Debug logging (only appears in development)
    debug(`Creating user: ${userData.email}`);
    
    // Deprecation warning for old API usage
    if (userData.userName) {
      deprecate('userName is deprecated, use username instead', false, {
        id: 'user-service.user-name-deprecated',
        until: '4.0.0',
        url: 'https://example.com/migration-guide'
      });
      userData.username = userData.userName;
    }
    
    // Development-only code
    runInDebug(() => {
      console.log('User creation debug info:', {
        timestamp: new Date(),
        userData: userData,
        stackTrace: new Error().stack
      });
    });
    
    return this.store.createRecord('user', userData);
  }
}

// Component example
export default class FormComponent extends Component {
  @action
  submitForm(event) {
    event.preventDefault();
    
    const formData = new FormData(event.target);
    const email = formData.get('email');
    const password = formData.get('password');
    
    // Validate inputs with assertions
    assert('Email is required for form submission', email);
    assert('Password is required for form submission', password);
    
    // Warn about potential issues
    warn('Password is very short', password.length >= 8, {
      id: 'form.weak-password'
    });
    
    debug(`Form submitted with email: ${email}`);
    
    this.onSubmit?.({ email, password });
  }
}

Object Inspection

Functions for inspecting and debugging object state.

/**
 * Create detailed string representation of object for debugging
 * @param obj - Object to inspect
 * @param options - Inspection options
 * @returns String representation of object
 */
function inspect(obj: any, options?: InspectOptions): string;

Usage Examples:

import { inspect } from "@ember/debug";

export default class DebuggingService extends Service {
  @tracked debugData = null;
  
  @action
  captureState() {
    const appState = {
      currentUser: this.session.currentUser,
      route: this.router.currentRouteName,
      queryParams: this.router.currentRoute.queryParams,
      timestamp: new Date()
    };
    
    // Create detailed inspection for debugging
    const inspected = inspect(appState, {
      depth: 3,
      showHidden: false,
      showProxy: true
    });
    
    console.log('Application state:', inspected);
    this.debugData = inspected;
  }
  
  @action
  inspectObject(object) {
    console.log('Object details:', inspect(object));
    
    // Different inspection levels
    console.log('Shallow:', inspect(object, { depth: 1 }));
    console.log('Deep:', inspect(object, { depth: 5 }));
  }
}

Debug Adapters

Adapter classes for integrating with browser developer tools.

/**
 * Container debug adapter for inspecting dependency injection container
 */
class ContainerDebugAdapter extends EmberObject {
  /**
   * Create container debug adapter
   * @param properties - Adapter properties
   * @returns ContainerDebugAdapter instance
   */
  static create(properties?: object): ContainerDebugAdapter;
  
  /**
   * Get all registered factories by type
   * @param type - Factory type (e.g., 'service', 'route', 'component')
   * @returns Array of factory information
   */
  catalogEntriesByType(type: string): FactoryInfo[];
  
  /**
   * Get container information
   * @returns Container debug information
   */
  getContainerInfo(): ContainerInfo;
}

/**
 * Data adapter for inspecting data layer (typically for Ember Data)
 */
class DataAdapter extends EmberObject {
  /**
   * Create data debug adapter
   * @param properties - Adapter properties
   * @returns DataAdapter instance
   */
  static create(properties?: object): DataAdapter;
  
  /**
   * Get model types for data inspector
   * @returns Array of model type information
   */
  getModelTypes(): ModelTypeInfo[];
  
  /**
   * Get records for a model type
   * @param modelType - Model type to get records for
   * @returns Array of record information
   */
  getRecords(modelType: string): RecordInfo[];
  
  /**
   * Watch model type for changes
   * @param modelType - Model type to watch
   * @param recordsAdded - Callback for added records
   * @param recordsUpdated - Callback for updated records
   * @param recordsRemoved - Callback for removed records
   * @returns Release function to stop watching
   */
  watchModelType(
    modelType: string,
    recordsAdded: (records: any[]) => void,
    recordsUpdated: (records: any[]) => void,
    recordsRemoved: (records: any[]) => void
  ): () => void;
}

Error Handling

Development-time error handling and reporting utilities.

/**
 * Register global error handler for development debugging
 * @param handler - Error handling function
 */
function registerErrorHandler(handler: (error: Error) => void): void;

/**
 * Register warning handler for custom warning processing
 * @param handler - Warning handling function
 */
function registerWarnHandler(handler: (message: string, options: any, next: Function) => void): void;

/**
 * Register deprecation handler for custom deprecation processing
 * @param handler - Deprecation handling function
 */
function registerDeprecationHandler(handler: (message: string, options: any, next: Function) => void): void;

Usage Examples:

import { 
  registerErrorHandler, 
  registerWarnHandler, 
  registerDeprecationHandler 
} from "@ember/debug";

// Custom error tracking in development
if (ENV.environment === 'development') {
  registerErrorHandler((error) => {
    console.group('🚨 Ember Error');
    console.error('Error:', error.message);
    console.error('Stack:', error.stack);
    console.error('Context:', {
      route: window.location.pathname,
      timestamp: new Date().toISOString()
    });
    console.groupEnd();
    
    // Send to error tracking service
    this.errorTracking.captureException(error);
  });
  
  registerWarnHandler((message, options, next) => {
    // Custom warning processing
    console.warn(`⚠️ Warning: ${message}`, options);
    
    // Log to analytics
    this.analytics.track('ember-warning', {
      message,
      id: options?.id,
      url: options?.url
    });
    
    // Call default handler
    next(message, options);
  });
  
  registerDeprecationHandler((message, options, next) => {
    // Track deprecation usage
    this.analytics.track('ember-deprecation', {
      message,
      id: options?.id,
      until: options?.until
    });
    
    // Call default handler
    next(message, options);
  });
}

Development Utilities

Additional utilities for development and debugging workflows.

/**
 * Get Ember version information
 * @returns Version string
 */
function getEmberVersion(): string;

/**
 * Check if running in development environment
 * @returns Whether in development mode
 */
function isDevelopment(): boolean;

/**
 * Check if running in testing environment
 * @returns Whether in testing mode
 */
function isTesting(): boolean;

/**
 * Enable or disable specific debug features
 * @param feature - Feature name to toggle
 * @param enabled - Whether to enable the feature
 */
function toggleDebugFeature(feature: string, enabled: boolean): void;

Usage Examples:

import { 
  getEmberVersion, 
  isDevelopment, 
  isTesting,
  toggleDebugFeature 
} from "@ember/debug";

export default class ApplicationController extends Controller {
  init() {
    super.init(...arguments);
    
    if (isDevelopment()) {
      console.log(`Running Ember ${getEmberVersion()}`);
      
      // Enable additional debugging features
      toggleDebugFeature('ds-warn-on-unknown-keys', true);
      toggleDebugFeature('ds-improve-debug', true);
      
      // Add global debugging helpers
      window.debugApp = this;
      window.inspectRoute = () => {
        const route = this.router.currentRoute;
        console.log('Current route:', inspect(route));
      };
    }
    
    if (isTesting()) {
      // Disable certain features in testing
      toggleDebugFeature('ds-warn-on-unknown-keys', false);
    }
  }
}

Types

interface WarnOptions {
  /** Unique identifier for this warning */
  id?: string;
  
  /** URL with more information */
  url?: string;
}

interface DeprecateOptions {
  /** Unique identifier for this deprecation */
  id: string;
  
  /** Version when this will be removed */
  until: string;
  
  /** URL with migration information */
  url?: string;
  
  /** Additional context */
  for?: string;
  
  /** Since which version this is deprecated */
  since?: string;
}

interface InspectOptions {
  /** Maximum depth to inspect */
  depth?: number;
  
  /** Show hidden properties */
  showHidden?: boolean;
  
  /** Show proxy information */
  showProxy?: boolean;
  
  /** Custom colors */
  colors?: boolean;
}

interface FactoryInfo {
  /** Factory name */
  name: string;
  
  /** Factory type */
  type: string;
  
  /** Whether factory is singleton */
  singleton: boolean;
  
  /** Whether factory is instantiable */
  instantiate: boolean;
}

interface ContainerInfo {
  /** Registered factories */
  registrations: Record<string, any>;
  
  /** Container cache */
  cache: Record<string, any>;
  
  /** Factory cache */
  factoryManagerCache: Record<string, any>;
}

interface ModelTypeInfo {
  /** Model name */
  name: string;
  
  /** Model count */
  count: number;
  
  /** Model columns/attributes */
  columns: ColumnInfo[];
}

interface RecordInfo {
  /** Record identifier */
  id: string;
  
  /** Record attributes */
  attributes: Record<string, any>;
  
  /** Record relationships */
  relationships: Record<string, any>;
}

interface ColumnInfo {
  /** Column name */
  name: string;
  
  /** Column description */
  desc: string;
}