Skip to Content
šŸŽ‰ Welcome to handit.ai Documentation!
TracingTracing GuideNode Function Tracing

Node Function Tracing

Maximum flexibility for programmatic tracing. Node function tracing allows you to trace any function call with complete control over when and how the tracing happens, perfect for custom tracking patterns, dynamic function calls, and integrating tracing into existing codebases.

This approach gives you the ultimate flexibility to trace functions programmatically, including functions you can’t modify directly or need conditional tracing.

Node function tracing gives you the most flexibility to trace functions programmatically, including functions you can’t modify directly or need conditional tracing.

How It Works

Node function tracing provides programmatic control through:

  • Programmatic control - Call tracing functions directly in your code
  • Dynamic tracing - Decide at runtime what to trace
  • Custom keys - Use custom identifiers for tracking
  • Flexible input handling - Works with any function signature
  • Error capture - Automatically handles and reports errors

Implementation

Python: trace_agent_node_func & trace_agent_node_func_sync

JavaScript: captureAgentNode

node_function.js
const { config, captureAgentNode } = require('handit-sdk'); config({ apiKey: 'your-api-key' }); // Example: Dynamic function tracing async function processUserRequest(userId, requestType, data) { let result; if (requestType === 'analysis') { // Trace the analysis function const analysisResult = await analyzeData(data); // Manually capture the execution await captureAgentNode({ agentNodeSlug: 'data-analysis', requestBody: { userId, data }, responseBody: analysisResult }); result = analysisResult; } else if (requestType === 'recommendation') { // Trace with custom key based on user const recommendations = await generateRecommendations(userId, data); await captureAgentNode({ agentNodeSlug: `recommendations-${userId}`, requestBody: { userId, preferences: data }, responseBody: recommendations }); result = recommendations; } else if (requestType === 'search') { // Trace with error handling try { const searchResults = await searchKnowledgeBase(data.query, data.filters); await captureAgentNode({ agentNodeSlug: 'knowledge-search', requestBody: { query: data.query, filters: data.filters, userId }, responseBody: searchResults, error: false }); result = searchResults; } catch (error) { // Capture error case await captureAgentNode({ agentNodeSlug: 'knowledge-search', requestBody: { query: data.query, filters: data.filters, userId }, responseBody: { error: error.message }, error: true }); throw error; } } return result; } // Example: Tracing external API calls async function callExternalService(endpoint, payload) { const startTime = Date.now(); try { const response = await fetch(`https://api.external-service.com/${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); const duration = Date.now() - startTime; // Capture successful API call await captureAgentNode({ agentNodeSlug: `external-api-${endpoint}`, requestBody: { endpoint, payload, timestamp: startTime }, responseBody: { ...result, duration, status: response.status } }); return result; } catch (error) { const duration = Date.now() - startTime; // Capture failed API call await captureAgentNode({ agentNodeSlug: `external-api-${endpoint}`, requestBody: { endpoint, payload, timestamp: startTime }, responseBody: { error: error.message, duration, failed: true }, error: true }); throw error; } } // Example functions async function analyzeData(data) { // Complex analysis logic const analysis = await performComplexAnalysis(data); return { analysis, confidence: 0.95 }; } async function generateRecommendations(userId, preferences) { const userProfile = await getUserProfile(userId); const recommendations = await mlRecommendationEngine(userProfile, preferences); return recommendations; } async function searchKnowledgeBase(query, filters) { const results = await vectorSearch(query, filters); return { results, count: results.length }; }

Advanced Use Cases

Conditional Tracing Based on Context

Tracing Third-Party Libraries

Best Practices

When to Use Node Function Tracing:

Use CaseWhy Node Function Tracing
Dynamic function selectionChoose which functions to trace based on runtime conditions
Third-party library integrationTrace external libraries and APIs without modifying their code
Conditional tracing logicImplement complex tracing rules based on environment or user context
Custom tracking patternsCreate specialized tracing workflows for unique requirements
Error-specific tracingFocus tracing on error scenarios and edge cases

Implementation Guidelines:

  1. Use descriptive keys for tracking - Choose meaningful identifiers that help with debugging and analysis
  2. Include relevant context in captures - Add metadata that provides useful debugging information
  3. Handle errors explicitly - Implement proper error handling and capture error scenarios
  4. Consider performance impact - Balance tracing detail with system performance requirements
  5. Add metadata for debugging - Include timing, user context, and other relevant information
āš ļø

Node function tracing requires more manual work but provides maximum flexibility. Use it when decorators and wrappers don’t fit your use case.

Node function tracing is perfect for integrating Handit.ai into existing codebases without major refactoring.

Next Steps

Last updated on