Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add error tracking functionality #452

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/forge_tracker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ anyhow.workspace = true

[dev-dependencies]
lazy_static.workspace = true
strum.workspace = true
strum.workspace = true
67 changes: 67 additions & 0 deletions crates/forge_tracker/src/error_tracking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::backtrace::Backtrace;

use lazy_static::lazy_static;

use crate::{ErrorDetails, EventKind, Tracker};

lazy_static! {
static ref TRACKER: Tracker = Tracker::default();
}

pub async fn track_error(
error_type: impl Into<String>,
message: impl Into<String>,
context: impl Into<String>,
) -> crate::Result<()> {
let details = ErrorDetails {
error_type: error_type.into(),
message: message.into(),
context: context.into(),
stack_trace: Some(Backtrace::force_capture().to_string()),
};

TRACKER.dispatch(EventKind::ErrorOccurred(details)).await
}

pub async fn track_error_without_trace(
error_type: impl Into<String>,
message: impl Into<String>,
context: impl Into<String>,
) -> crate::Result<()> {
let details = ErrorDetails {
error_type: error_type.into(),
message: message.into(),
context: context.into(),
stack_trace: None,
};

TRACKER.dispatch(EventKind::ErrorOccurred(details)).await
}

#[cfg(test)]
mod tests {

use super::*;

#[tokio::test]
async fn test_track_error() {
let result = track_error(
"TestError",
"Test error message",
"test_track_error function",
)
.await;
assert!(result.is_ok());
}

#[tokio::test]
async fn test_track_error_without_trace() {
let result = track_error_without_trace(
"TestError",
"Test error message",
"test_track_error_without_trace function",
)
.await;
assert!(result.is_ok());
}
}
11 changes: 11 additions & 0 deletions crates/forge_tracker/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ use chrono::{DateTime, Utc};
use convert_case::{Case, Casing};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ErrorDetails {
pub error_type: String,
pub message: String,
pub context: String,
pub stack_trace: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Event {
pub event_name: Name,
Expand Down Expand Up @@ -47,6 +55,7 @@ pub enum EventKind {
Start,
Ping,
Prompt(String),
ErrorOccurred(ErrorDetails),
}

impl EventKind {
Expand All @@ -55,13 +64,15 @@ impl EventKind {
Self::Start => Name::from("start".to_string()),
Self::Ping => Name::from("ping".to_string()),
Self::Prompt(_) => Name::from("prompt".to_string()),
Self::ErrorOccurred(_) => Name::from("error_occurred".to_string()),
}
}
pub fn value(&self) -> String {
match self {
Self::Start => "".to_string(),
Self::Ping => "".to_string(),
Self::Prompt(content) => content.to_string(),
Self::ErrorOccurred(details) => serde_json::to_string(details).unwrap_or_default(),
}
}
}
5 changes: 4 additions & 1 deletion crates/forge_tracker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ mod can_track;
mod collect;
mod dispatch;
mod error;
mod error_tracking;
mod event;
mod log;

pub use can_track::VERSION;
pub use dispatch::Tracker;
use error::Result;
pub use event::{Event, EventKind};
pub use error_tracking::{track_error, track_error_without_trace};
pub use event::{ErrorDetails, Event, EventKind};
pub use log::{init_tracing, Guard};
54 changes: 54 additions & 0 deletions docs/error-tracking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
layout: page
title: Error Tracking
nav_order: 5
description: "Runtime error tracking in Code-Forge"
---

# Error Tracking

Code-Forge now includes error tracking to monitor issues that occur during AI-assisted development operations. This helps improve the reliability of AI-powered code generation, manipulation, and analysis tasks.

## Features

- **AI Operation Monitoring**
- Track errors in code generation and manipulation
- Monitor AI model integration issues
- Capture tool execution failures
- Track file system operation errors

## Usage

Track errors during AI operations:
```rust
use forge_tracker::track_error;

track_error(
"CodeGenerationError",
"Failed to generate code: Invalid syntax in template",
"code_generator.generate_function"
).await?;
```

Track file system operation errors:
```rust
use forge_tracker::track_error_without_trace;

track_error_without_trace(
"FileSystemError",
"Failed to create file: Permission denied",
"fs_tool.create_file"
).await?;
```

## Benefits

Error tracking helps improve Forge's AI assistance by:
- Identifying common failure patterns in AI operations
- Monitoring the reliability of different code manipulation tasks
- Helping prioritize improvements to AI models and tools
- Measuring the effectiveness of AI-related fixes

## Privacy

Error tracking respects Forge's tracking preferences. If tracking is disabled, no error information will be collected.
9 changes: 8 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,11 @@ Code-Forge provides several powerful features:
- Extensible tool system
- JSON schema-based tool definitions
- Asynchronous tool execution
- Error handling and validation
- Error handling and validation

5. **Error Tracking**
- Comprehensive error monitoring
- Stack trace collection
- Error categorization and context
- Opt-out respecting privacy preferences
- Error frequency analysis
Loading