Agent skill

error-tracking

Add error tracking and performance monitoring to your project services. Use this skill when adding error handling, creating new controllers/routes, instrumenting background jobs, or tracking performance. Supports Sentry, Datadog, and other monitoring solutions. ALL ERRORS MUST BE CAPTURED - no exceptions.

Stars 1
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/fghaffar/claude-cursor-setup/tree/main/skills/error-tracking

SKILL.md

Error Tracking Integration Skill

Purpose

This skill enforces comprehensive error tracking and performance monitoring across all services. Customize the patterns below for your specific monitoring solution (Sentry, Datadog, New Relic, etc.).

When to Use This Skill

  • Adding error handling to any code
  • Creating new controllers or routes
  • Instrumenting background jobs / cron tasks
  • Tracking database or API performance
  • Adding performance spans
  • Handling async operation errors

CRITICAL RULE

ALL ERRORS MUST BE CAPTURED TO YOUR MONITORING SERVICE - No exceptions. Never use console.error alone.


Integration Patterns

1. Controller/Route Error Handling

Python (FastAPI)

python
import logging
import sentry_sdk  # or your monitoring library

logger = logging.getLogger(__name__)

@router.get("/items/{item_id}")
async def get_item(item_id: str):
    try:
        result = await item_service.get_item(item_id)
        return result
    except ItemNotFoundError as e:
        logger.warning("Item not found", extra={"item_id": item_id})
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error("Unexpected error", extra={"item_id": item_id, "error": str(e)}, exc_info=True)
        sentry_sdk.capture_exception(e)
        raise HTTPException(status_code=500, detail="Internal server error")

TypeScript (Express/Node.js)

typescript
import * as Sentry from '@sentry/node';

router.get('/items/:id', async (req, res) => {
    try {
        const result = await itemService.getItem(req.params.id);
        res.json(result);
    } catch (error) {
        Sentry.captureException(error, {
            tags: { route: '/items/:id', method: 'GET' },
            extra: { itemId: req.params.id, userId: req.user?.id }
        });
        res.status(500).json({ error: 'Internal server error' });
    }
});

2. Service Layer Error Handling

python
# Python
class ItemService:
    async def create_item(self, data: ItemCreate) -> Item:
        try:
            item = await self.repository.create(data)
            return item
        except IntegrityError as e:
            logger.warning("Duplicate item", extra={"data": data.model_dump()})
            raise DuplicateItemError("Item already exists")
        except Exception as e:
            logger.error("Failed to create item", extra={"error": str(e)}, exc_info=True)
            sentry_sdk.capture_exception(e)
            raise
typescript
// TypeScript
class ItemService {
    async createItem(data: CreateItemDto): Promise<Item> {
        try {
            return await this.repository.create(data);
        } catch (error) {
            if (error instanceof DuplicateKeyError) {
                logger.warn('Duplicate item', { data });
                throw new ConflictError('Item already exists');
            }
            logger.error('Failed to create item', { error, data });
            Sentry.captureException(error);
            throw error;
        }
    }
}

3. Background Jobs / Cron Tasks

typescript
#!/usr/bin/env node
// CRITICAL: Import monitoring first!
import './instrument';
import * as Sentry from '@sentry/node';

async function main() {
    return await Sentry.startSpan({
        name: 'cron.job-name',
        op: 'cron',
        attributes: {
            'cron.job': 'job-name',
            'cron.startTime': new Date().toISOString(),
        }
    }, async () => {
        try {
            // Your job logic here
            await processItems();
        } catch (error) {
            Sentry.captureException(error, {
                tags: {
                    'cron.job': 'job-name',
                    'error.type': 'execution_error'
                }
            });
            console.error('[Job] Error:', error);
            process.exit(1);
        }
    });
}

main()
    .then(() => {
        console.log('[Job] Completed successfully');
        process.exit(0);
    })
    .catch((error) => {
        console.error('[Job] Fatal error:', error);
        process.exit(1);
    });
python
# Python (Celery)
import sentry_sdk
from celery import Celery

@celery_app.task(bind=True, max_retries=3)
def process_items(self):
    try:
        # Your task logic here
        result = do_processing()
        return result
    except TransientError as e:
        logger.warning("Transient error, retrying", extra={"error": str(e)})
        raise self.retry(exc=e, countdown=60)
    except Exception as e:
        logger.error("Task failed", extra={"error": str(e)}, exc_info=True)
        sentry_sdk.capture_exception(e)
        raise

4. Performance Monitoring

typescript
import * as Sentry from '@sentry/node';

// Wrap slow operations with spans
const result = await Sentry.startSpan({
    name: 'database.query',
    op: 'db.query',
    attributes: {
        'db.operation': 'findMany',
        'db.table': 'items'
    }
}, async () => {
    return await prisma.item.findMany({ take: 100 });
});
python
# Python with Sentry
import sentry_sdk

with sentry_sdk.start_span(op="db.query", description="Find items") as span:
    span.set_tag("db.table", "items")
    result = await db.items.find_many(limit=100)

Error Levels

Use appropriate severity levels:

Level When to Use
fatal System is unusable (database down, critical service failure)
error Operation failed, needs immediate attention
warning Recoverable issues, degraded performance
info Informational messages, successful operations
debug Detailed debugging information (dev only)

Required Context

Always include relevant context with errors:

typescript
import * as Sentry from '@sentry/node';

Sentry.withScope((scope) => {
    // User context
    scope.setUser({ id: userId, email: userEmail });

    // Service/environment tags
    scope.setTag('service', 'api');
    scope.setTag('environment', process.env.NODE_ENV);

    // Operation-specific context
    scope.setContext('operation', {
        type: 'item.create',
        itemId: itemId,
        timestamp: new Date().toISOString()
    });

    Sentry.captureException(error);
});
python
import sentry_sdk

with sentry_sdk.push_scope() as scope:
    scope.set_user({"id": user_id, "email": user_email})
    scope.set_tag("service", "api")
    scope.set_context("operation", {
        "type": "item.create",
        "item_id": item_id,
    })
    sentry_sdk.capture_exception(error)

Configuration Templates

Sentry (Node.js)

typescript
// instrument.ts - Import this FIRST in your app
import * as Sentry from '@sentry/node';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

Sentry.init({
    dsn: process.env.SENTRY_DSN,
    environment: process.env.NODE_ENV || 'development',
    integrations: [
        nodeProfilingIntegration(),
    ],
    tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
    profilesSampleRate: 0.1,
});

Sentry (Python)

python
# instrument.py - Import this FIRST in your app
import sentry_sdk
from sentry_sdk.integrations.fastapi import FastApiIntegration
from sentry_sdk.integrations.celery import CeleryIntegration

sentry_sdk.init(
    dsn=os.environ.get("SENTRY_DSN"),
    environment=os.environ.get("ENVIRONMENT", "development"),
    integrations=[
        FastApiIntegration(),
        CeleryIntegration(),
    ],
    traces_sample_rate=0.1 if os.environ.get("ENVIRONMENT") == "production" else 1.0,
)

Environment Variables

bash
# .env
SENTRY_DSN=https://your-dsn@sentry.io/project
ENVIRONMENT=development

Common Mistakes to Avoid

Don't Do Instead
console.error(error) only logger.error() + captureException()
Swallow errors silently Always log + capture
Expose internal errors to clients Return generic error messages
Generic error messages without context Add meaningful context to all errors
Skip error handling in async operations Always wrap async with try-catch
Forget to import instrument first Import monitoring setup as first import

Implementation Checklist

When adding error tracking to new code:

  • Imported monitoring library or helper
  • All try/catch blocks capture to monitoring service
  • Added meaningful context to errors
  • Used appropriate error level (fatal/error/warning/info)
  • No sensitive data in error messages
  • Added performance tracking for slow operations
  • Tested error handling paths
  • For cron jobs: instrument file imported first

Customization Notes

Replace these for your project:

  1. Monitoring Service: Replace Sentry with your solution (Datadog, New Relic, etc.)
  2. Import Statements: Update import paths for your project structure
  3. Environment Variables: Match your configuration pattern
  4. Service Names: Use your actual service names in tags
  5. Framework Integrations: Add integrations for your frameworks

Related Skills

  • backend-dev-guidelines - General backend patterns
  • frontend-dev-guidelines - Frontend error boundaries
  • skill-developer - Creating monitoring-specific skills

Expand your agent's capabilities with these related and highly-rated skills.

fghaffar/claude-cursor-setup

github-code-reviewer

Review GitHub PRs with surgical precision. Flag only high-severity issues (bugs, security, performance, breaking changes) via succinct inline comments on specific lines. Skip style, nits, and minor improvements. High signal, low noise.

1 0
Explore
fghaffar/claude-cursor-setup

skill-developer

Create and manage Claude Code skills following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns, file paths, content patterns), enforcement levels (block, suggest, warn), hook mechanisms (UserPromptSubmit, PreToolUse), session tracking, and the 500-line rule.

1 0
Explore
fghaffar/claude-cursor-setup

backend-dev-guidelines

Backend development guidelines for FastAPI + Python with PostgreSQL/pgvector and async patterns

1 0
Explore
fghaffar/claude-cursor-setup

frontend-dev-guidelines

Frontend development guidelines for Next.js 15 + React 19 + TypeScript with Tailwind CSS and TanStack Query

1 0
Explore
mattpocock/skills

handoff

Compact the current conversation into a handoff document for another agent to pick up.

111,310 9,758
Explore
mattpocock/skills

obsidian-vault

Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.

111,310 9,758
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results