or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

edge-cases.mddocs/examples/

Edge Cases and Error Handling

Advanced scenarios, edge cases, and error handling patterns for Dash0 Web SDK.

Initialization Edge Cases

Multiple Initialization

// First initialization
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
});

// Second initialization - may override or merge
init({
  serviceName: "my-website-v2",
  endpoint: { url: "...", authToken: "..." },
});

Behavior: Last configuration typically takes precedence, but behavior may vary.

Missing Required Fields

// This may fail silently or throw an error
init({
  serviceName: "my-website",
  // endpoint is missing!
});

Handling: Always validate configuration before calling init().

Invalid Endpoint URL

init({
  serviceName: "my-website",
  endpoint: {
    url: "not-a-valid-url",  // Invalid URL
    authToken: "token",
  },
});

Behavior: SDK initializes but telemetry transmission fails.

Storage Edge Cases

Storage Unavailable (Private Browsing)

// In private browsing mode, storage may be unavailable
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
});

// Sessions will reset on each page load
// Attributes may not persist

Handling: Check storage availability and inform users if needed.

Storage Quota Exceeded

// If storage quota is exceeded
try {
  addSignalAttribute("large.data", veryLargeData);
} catch (error) {
  // Handle quota exceeded error
  console.warn("Storage quota exceeded, attribute not saved");
}

Behavior: SDK falls back to in-memory storage, data doesn't persist.

Storage Corruption

// If stored data is corrupted, SDK may reset
// No explicit handling needed - SDK handles automatically

Network Edge Cases

Offline Mode

// Telemetry is queued when offline
sendEvent("user_action");

// When online, queued telemetry is transmitted
// No explicit handling needed

Network Failures

// SDK continues to operate even if endpoint is unreachable
init({
  serviceName: "my-website",
  endpoint: {
    url: "https://unreachable-endpoint.com",
    authToken: "token",
  },
});

// Telemetry may be queued or dropped
// SDK doesn't throw errors

CORS Errors

// Ensure endpoint allows CORS
init({
  serviceName: "my-website",
  endpoint: {
    url: "https://cors-enabled-endpoint.com",
    authToken: "token",
  },
});

// If CORS is not configured, requests will fail silently

Session Edge Cases

Session Expiration

// Sessions expire based on timeouts
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
  sessionInactivityTimeoutMillis: 1800000,  // 30 minutes
  sessionTerminationTimeoutMillis: 3600000,  // 1 hour
});

// After timeout, new session is created on next page load

Multiple Tabs

// Multiple tabs share session state (via storage)
// Tab 1
identify("user-123");

// Tab 2 (same domain)
// User is already identified (shared state)

// Some browsers isolate storage per tab
// In that case, each tab has separate session

Error Handling Patterns

Try-Catch with Error Reporting

import { reportError } from "@dash0/sdk-web";

async function riskyOperation() {
  try {
    const result = await performOperation();
    return result;
  } catch (error) {
    // Report error but don't break user experience
    reportError(error, {
      attributes: {
        "operation": "risky_operation",
        "error.context": "user_flow",
      },
    });
    
    // Show user-friendly error
    showErrorMessage("Something went wrong. Please try again.");
    
    // Return fallback
    return getFallbackData();
  }
}

Promise Chain Error Handling

import { reportError } from "@dash0/sdk-web";

fetchData()
  .then(processData)
  .then(displayData)
  .catch((error) => {
    reportError(error, {
      attributes: {
        "operation": "data_processing",
      },
    });
    handleError(error);
  });

React Error Boundary

import { reportError } from "@dash0/sdk-web";

class ErrorBoundary extends React.Component {
  componentDidCatch(error, errorInfo) {
    reportError(error, {
      componentStack: errorInfo.componentStack,
      attributes: {
        "error.boundary": this.constructor.name,
        "error.recoverable": true,
      },
    });
  }
  
  render() {
    if (this.state.hasError) {
      return <ErrorFallback />;
    }
    return this.props.children;
  }
}

Timing Edge Cases

Early Initialization

// Initialize in <head> before DOM is ready
// Some DOM-based instrumentations may not work
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
});

Late Initialization

// Initialize after page load
// Early events (navigation timing, web vitals) may be missed
window.addEventListener("load", () => {
  init({
    serviceName: "my-website",
    endpoint: { url: "...", authToken: "..." },
  });
});

Clock Skew

// System clock changes may affect timestamps
// SDK handles this automatically, but be aware of potential issues
sendEvent("scheduled_event", {
  timestamp: new Date(),  // May be affected by clock changes
});

Browser Compatibility Edge Cases

Missing Browser APIs

// Check for required APIs before initialization
if (typeof fetch === "undefined" || typeof localStorage === "undefined") {
  console.warn("Required browser APIs not available");
  // Fallback behavior or show warning to user
} else {
  init({
    serviceName: "my-website",
    endpoint: { url: "...", authToken: "..." },
  });
}

Ad Blockers

// Ad blockers may block telemetry transmission
// SDK continues to operate but telemetry may not be sent
// No explicit error is thrown

Content Security Policy

// Strict CSP may block inline scripts or external resources
// Ensure CSP allows:
// - script-src 'self' 'unsafe-inline' https://unpkg.com
// - connect-src 'self' https://ingress.dash0.com

Performance Edge Cases

High Telemetry Volume

// Very high telemetry volume may impact performance
// Throttle events if needed
let eventCount = 0;
const MAX_EVENTS_PER_SECOND = 10;

function throttledSendEvent(name, opts) {
  if (eventCount < MAX_EVENTS_PER_SECOND) {
    sendEvent(name, opts);
    eventCount++;
    setTimeout(() => eventCount--, 1000);
  }
}

Large Payloads

// Very large event payloads may cause transmission issues
// Consider splitting large data
const largeData = { /* very large object */ };

// Instead of sending all at once
sendEvent("large_data", { data: largeData });

// Split into smaller chunks
Object.entries(largeData).forEach(([key, value]) => {
  sendEvent("data_chunk", {
    attributes: { "chunk.key": key },
    data: value,
  });
});

User Identification Edge Cases

Multiple Identify Calls

// Multiple calls merge attributes, don't replace
identify("user-123", { name: "John" });
identify("user-123", { email: "john@example.com" });

// Result: user has both name and email
// Not: user only has email (previous attributes not lost)

Clearing User Data

import { removeSignalAttribute } from "@dash0/sdk-web";

// Must explicitly remove each attribute
function clearUserData() {
  removeSignalAttribute("user.id");
  removeSignalAttribute("user.name");
  removeSignalAttribute("user.email");
  removeSignalAttribute("user.roles");
}

Event Edge Cases

Internal Event Names

// These event names are reserved and will be dropped
sendEvent("browser.page_view", {});      // Dropped
sendEvent("browser.navigation_timing", {}); // Dropped
sendEvent("browser.web_vital", {});       // Dropped
sendEvent("browser.error", {});           // Dropped

// Use custom names instead
sendEvent("custom.page_view", {});

Future/Past Timestamps

// Future timestamps are allowed (for scheduled events)
sendEvent("scheduled_event", {
  timestamp: new Date(Date.now() + 86400000), // Tomorrow
});

// Past timestamps are allowed (for retroactive logging)
sendEvent("past_event", {
  timestamp: new Date(Date.now() - 86400000), // Yesterday
});

Configuration Edge Cases

Invalid Configuration Values

// Invalid values may be ignored or cause errors
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
  sessionInactivityTimeoutMillis: -1000,  // Invalid: negative
  // May use default or cause error
});

Regex Pattern Errors

// Invalid regex patterns may cause errors
init({
  serviceName: "my-website",
  endpoint: { url: "...", authToken: "..." },
  ignoreUrls: [/invalid[regex/,  // Invalid regex
  ],
});

Best Practices for Edge Cases

  1. Validate Configuration: Check required fields before initialization
  2. Handle Storage Failures: Be aware that storage may be unavailable
  3. Monitor Network: SDK handles network failures, but monitor for issues
  4. Test Multiple Tabs: Verify behavior across multiple tabs
  5. Handle Errors Gracefully: Report errors but don't break user experience
  6. Throttle High-Frequency Events: Limit event frequency to avoid performance issues
  7. Test Browser Compatibility: Verify behavior in target browsers
  8. Monitor Performance: Watch for performance impacts from telemetry

See Reference Documentation for complete API details.