---
sidebar_position: 6
---

# Frontend Error Tracking

Capturing, analyzing, and debugging JavaScript errors using agnt's proxy.

## Overview

The proxy automatically captures:

- **Uncaught exceptions** - `window.onerror`
- **Unhandled promise rejections** - `unhandledrejection` events
- **Custom errors** - Via `window.__devtool.error()`

All errors include stack traces, source locations, and page context.

## Viewing Captured Errors

### Query Error Logs

```json
proxylog {proxy_id: "app", types: ["error"]}
→ {
    entries: [
      {
        type: "error",
        timestamp: "2024-01-15T10:32:15Z",
        message: "Cannot read property 'map' of undefined",
        source: "http://localhost:8080/static/js/main.js",
        line: 142,
        column: 23,
        stack: "TypeError: Cannot read property 'map' of undefined\n    at UserList (main.js:142:23)\n    at renderWithHooks...",
        url: "http://localhost:8080/users",
        userAgent: "Mozilla/5.0..."
      }
    ]
  }
```

### Filter by Time

```json
// Errors in the last 5 minutes
proxylog {proxy_id: "app", types: ["error"], since: "5m"}

// Errors in a specific window
proxylog {proxy_id: "app", types: ["error"], since: "2024-01-15T10:00:00Z", until: "2024-01-15T11:00:00Z"}
```

### Get Error Statistics

```json
proxylog {proxy_id: "app", action: "stats"}
→ {
    by_type: {
      http: 1500,
      error: 12,
      performance: 45
    }
  }
```

## Correlating Errors with Traffic

### Find What API Calls Preceded an Error

```json
// Get error timestamp
proxylog {proxy_id: "app", types: ["error"]}
→ Error at 10:32:15 on /users page

// Check API calls around that time
proxylog {
  proxy_id: "app",
  types: ["http"],
  url_pattern: "/api",
  since: "2024-01-15T10:32:00Z",
  until: "2024-01-15T10:32:20Z"
}
→ {
    entries: [
      {url: "/api/users", status: 500, response_body: "{\"error\": \"...\"}", timestamp: "10:32:14"}
    ]
  }
```

The API returned 500, causing the subsequent JavaScript error.

### Use Page Sessions

```json
// Get page session that had errors
currentpage {proxy_id: "app"}
→ {sessions: [{id: "page-1", error_count: 2, url: "/users"}]}

// Get full context
currentpage {proxy_id: "app", action: "get", session_id: "page-1"}
→ {
    resources: [
      {url: "/api/users", status: 500}
    ],
    errors: [
      {message: "Cannot read property 'map'..."}
    ],
    performance: {...}
  }
```

## Debugging Specific Errors

### Inspect Error Location

```json
// From error log, we know the component is UserList at line 142
// Inspect the component in the browser

proxy {action: "exec", id: "app", code: "window.__devtool.inspect('.user-list')"}
→ {
    element: {tag: "div", classes: ["user-list"]},
    visibility: {visible: true},
    // Check if element rendered at all
  }
```

### Check Application State

```json
// What's in localStorage/sessionStorage?
proxy {action: "exec", id: "app", code: "window.__devtool.captureState(['localStorage', 'sessionStorage'])"}

// Check for cached data
→ {
    localStorage: {users: null},  // Expected to have user data
    sessionStorage: {}
  }
```

### Reproduce the Error

```json
// Wait for the problematic component
proxy {action: "exec", id: "app", code: "window.__devtool.waitForElement('.user-list', 10000)"}

// If it never appears, the error prevented rendering
```

## Custom Error Logging

### Log from Application Code

```javascript
// In your application code
try {
  await fetchUsers();
} catch (error) {
  window.__devtool?.error('Failed to fetch users', {
    error: error.message,
    stack: error.stack,
    userId: currentUser.id
  });
}
```

### Query Custom Logs

```json
proxylog {proxy_id: "app", types: ["custom"]}
→ {
    entries: [
      {
        level: "error",
        message: "Failed to fetch users",
        data: {error: "Network error", userId: 123},
        timestamp: "..."
      }
    ]
  }
```

## Error Monitoring Patterns

### Real-Time Error Watch

```json
// Check for new errors periodically
proxylog {proxy_id: "app", types: ["error"], since: "1m"}
```

### Error Grouping

```json
proxy {action: "exec", id: "app", code: `
  // Group errors by message (simplified)
  const logs = await fetch('/__devtool_api/errors').then(r => r.json());
  const grouped = {};

  logs.forEach(err => {
    const key = err.message.replace(/\\d+/g, 'N');  // Normalize numbers
    grouped[key] = grouped[key] || {count: 0, examples: []};
    grouped[key].count++;
    if (grouped[key].examples.length < 3) {
      grouped[key].examples.push(err);
    }
  });

  grouped
`}
```

### Error Rate Tracking

```json
// Check error count
proxylog {proxy_id: "app", action: "stats"}
→ {by_type: {error: 12}}

// Compare to traffic
// If 12 errors in 1500 requests = 0.8% error rate
```

## Handling Specific Error Types

### Uncaught Exceptions

```json
proxylog {proxy_id: "app", types: ["error"]}
→ {
    message: "TypeError: Cannot read property 'x' of undefined",
    source: "main.js",
    line: 100
  }
```

Debug approach:
1. Check the source file and line
2. Inspect variables at that location
3. Check API responses that might have returned unexpected data

### Promise Rejections

```json
→ {
    message: "Unhandled Promise Rejection: NetworkError",
    source: "api.js",
    line: 45
  }
```

Debug approach:
1. Check network logs for failed requests
2. Add `.catch()` handlers to promises
3. Check if network was available

### Syntax Errors

```json
→ {
    message: "SyntaxError: Unexpected token '<'",
    source: "app.js",
    line: 1
  }
```

This usually means:
- JS file returned HTML (404 page)
- Build error produced invalid JS
- Script src is wrong

Check:
```json
proxylog {proxy_id: "app", types: ["http"], url_pattern: "app.js"}
→ Check Content-Type and response body
```

## Creating Error Reports

### Capture Error Context

```json
// When error is reported:

// 1. Screenshot
proxy {action: "exec", id: "app", code: "window.__devtool.screenshot('error-state')"}

// 2. DOM state
proxy {action: "exec", id: "app", code: "window.__devtool.captureDOM()"}

// 3. Application state
proxy {action: "exec", id: "app", code: "window.__devtool.captureState(['localStorage'])"}

// 4. Recent network
proxy {action: "exec", id: "app", code: "window.__devtool.captureNetwork()"}

// 5. Error details
proxylog {proxy_id: "app", types: ["error"], limit: 5}
```

### Automated Error Report

```json
proxy {action: "exec", id: "app", code: `
  const report = {
    timestamp: new Date().toISOString(),
    url: window.location.href,
    userAgent: navigator.userAgent,
    viewport: {
      width: window.innerWidth,
      height: window.innerHeight
    },
    state: window.__devtool.captureState(['localStorage']),
    recentErrors: [],  // Would need API call to get these
    screenshot: await window.__devtool.screenshot('error-report')
  };

  JSON.stringify(report, null, 2)
`}
```

## Integration with Error Tracking Services

### Send to External Service

```javascript
// In your app, forward errors
window.addEventListener('error', (event) => {
  // Log to devtool
  window.__devtool?.log(event.message, 'error', {
    source: event.filename,
    line: event.lineno
  });

  // Also send to Sentry/Datadog/etc
  Sentry.captureException(event.error);
});
```

### Compare with Production

```json
// Proxy captures same data as production error tracking
// Use for debugging before errors reach production
```

## Best Practices

1. **Always check errors first** - Many bugs start with JS errors
2. **Correlate with API calls** - Errors often caused by bad data
3. **Use page sessions** - See full context of error
4. **Capture state** - localStorage, DOM, network
5. **Screenshot** - Visual state at error time
6. **Check console too** - Some errors only in console

## Common Error Patterns

| Error | Likely Cause | Debug Steps |
|-------|--------------|-------------|
| `undefined is not a function` | Method on null | Check API response |
| `Cannot read property X` | Null reference | Trace data flow |
| `Network Error` | CORS, offline, 500 | Check HTTP logs |
| `Unexpected token <` | HTML instead of JS | Check Content-Type |
| `Script error.` | Cross-origin script | Check CORS headers |

## See Also

- [Debugging Web Apps](/use-cases/debugging-web-apps) - General debugging
- [Reverse Proxy](/features/reverse-proxy) - Proxy setup
- [proxylog](/api/proxylog) - Full API reference
