--- name: sentry-hello-world description: 'Capture your first test error with Sentry and verify it appears in the dashboard. Use when testing a new Sentry integration, verifying error capture works after install-auth, or learning how to enrich events with user context, tags, and breadcrumbs. Trigger with phrases like "test sentry", "sentry hello world", "verify sentry", "first sentry error", "sentry capture test". ' allowed-tools: Read, Write, Edit, Bash(node:*), Bash(python:*), Bash(npm:*), Grep version: 1.51.0 license: MIT author: Jeremy Longshore tags: - saas - sentry - testing - dashboard - quickstart compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw --- # Sentry Hello World ## Overview Send your first test events to Sentry — a captured message, a captured exception, and a fully-enriched error with user context, tags, and breadcrumbs — then verify each one appears in the Sentry dashboard. This skill covers both Node.js (`@sentry/node`) and Python (`sentry-sdk`). ## Prerequisites - Completed `sentry-install-auth` setup (SDK installed, DSN configured) - Valid `SENTRY_DSN` in environment variables - `instrument.mjs` loaded before app code (Node.js) or `sentry_sdk.init()` called (Python) - Network access to `*.ingest.sentry.io` ## Instructions ### Step 1 — Verify the SDK Is Active Before sending test events, confirm the SDK initialized correctly. If `getClient()` returns `undefined`, the SDK was never initialized — go back to `sentry-install-auth`. **TypeScript (Node.js):** ```typescript import * as Sentry from '@sentry/node'; const client = Sentry.getClient(); if (!client) { console.error('Sentry SDK not initialized. Ensure instrument.mjs is loaded first.'); console.error('Run with: node --import ./instrument.mjs your-script.mjs'); process.exit(1); } console.log('Sentry SDK active — DSN configured'); ``` **Python:** ```python import sentry_sdk client = sentry_sdk.Hub.current.client if client is None or client.dsn is None: print("Sentry SDK not initialized. Call sentry_sdk.init() first.") exit(1) print("Sentry SDK active — DSN configured") ``` ### Step 2 — Capture a Test Message `captureMessage` sends an informational event without a stack trace. Use it to verify basic connectivity between your app and Sentry. **TypeScript:** ```typescript import * as Sentry from '@sentry/node'; // captureMessage returns the event ID (a 32-char hex string) const eventId = Sentry.captureMessage('Hello Sentry! SDK verification test.', 'info'); console.log(`Message sent — Event ID: ${eventId}`); // Also test 'warning' level — appears with yellow indicator in dashboard Sentry.captureMessage('Warning-level test message', 'warning'); // IMPORTANT: flush before process exits or events may be lost await Sentry.flush(2000); ``` **Python:** ```python import sentry_sdk event_id = sentry_sdk.capture_message("Hello Sentry! SDK verification test.", level="info") print(f"Message sent — Event ID: {event_id}") sentry_sdk.capture_message("Warning-level test message", level="warning") # Flush to ensure delivery before process exits sentry_sdk.flush() ``` ### Step 3 — Capture a Test Exception `captureException` sends a full error with stack trace. Always pass an actual `Error` object (not a string) so Sentry generates a proper stack trace. **TypeScript:** ```typescript import * as Sentry from '@sentry/node'; try { throw new Error('Hello Sentry! This is a test exception.'); } catch (error) { const eventId = Sentry.captureException(error); console.log(`Exception sent — Event ID: ${eventId}`); } await Sentry.flush(2000); ``` **Python:** ```python import sentry_sdk try: raise ValueError("Hello Sentry! This is a test exception.") except Exception as e: event_id = sentry_sdk.capture_exception(e) print(f"Exception sent — Event ID: {event_id}") sentry_sdk.flush() ``` ### Step 4 — Add User Context and Tags Enrich events with identity and metadata so you can filter and search in the dashboard. `setUser` attaches to all subsequent events in the current scope. `setTag` creates indexed, searchable key-value pairs. **TypeScript:** ```typescript import * as Sentry from '@sentry/node'; // Attach user identity — appears in the "User" section of every event Sentry.setUser({ id: 'test-user-001', email: 'dev@example.com', username: 'developer', }); // Tags are indexed and searchable — use for filtering in Issues view Sentry.setTag('test_run', 'hello-world'); Sentry.setTag('team', 'platform'); // setContext adds structured data (not indexed, but visible in event detail) Sentry.setContext('test_metadata', { ran_at: new Date().toISOString(), node_version: process.version, purpose: 'SDK verification', }); // This event will carry user, tags, and context Sentry.captureMessage('Test event with full context attached', 'info'); await Sentry.flush(2000); ``` **Python:** ```python import sentry_sdk from datetime import datetime, timezone import sys sentry_sdk.set_user({"id": "test-user-001", "email": "dev@example.com", "username": "developer"}) sentry_sdk.set_tag("test_run", "hello-world") sentry_sdk.set_tag("team", "platform") sentry_sdk.set_context("test_metadata", { "ran_at": datetime.now(timezone.utc).isoformat(), "python_version": sys.version, "purpose": "SDK verification", }) sentry_sdk.capture_message("Test event with full context attached", level="info") sentry_sdk.flush() ``` ### Step 5 — Add Breadcrumbs Breadcrumbs record a trail of events leading up to an error. They appear in the event detail view, giving you the chronological context of what happened before the crash. **TypeScript:** ```typescript import * as Sentry from '@sentry/node'; Sentry.addBreadcrumb({ category: 'auth', message: 'User authenticated successfully', level: 'info', }); Sentry.addBreadcrumb({ category: 'http', message: 'GET /api/users returned 200', level: 'info', data: { status_code: 200, url: '/api/users', method: 'GET' }, }); Sentry.addBreadcrumb({ category: 'ui', message: 'User clicked "Submit Order" button', level: 'info', }); // This exception will carry all three breadcrumbs above try { throw new Error('Order processing failed — breadcrumb trail attached'); } catch (error) { Sentry.captureException(error); } await Sentry.flush(2000); ``` **Python:** ```python import sentry_sdk sentry_sdk.add_breadcrumb(category="auth", message="User authenticated successfully", level="info") sentry_sdk.add_breadcrumb(category="http", message="GET /api/users returned 200", level="info", data={"status_code": 200, "url": "/api/users"}) sentry_sdk.add_breadcrumb(category="ui", message="User clicked Submit Order button", level="info") try: raise RuntimeError("Order processing failed — breadcrumb trail attached") except Exception as e: sentry_sdk.capture_exception(e) sentry_sdk.flush() ``` ### Step 6 — Verify in the Sentry Dashboard 1. Open **https://sentry.io** and select your project 2. Navigate to the **Issues** tab — test errors appear as grouped issues 3. Click an issue to inspect the event detail: - **Stack Trace** — file path, line number, and surrounding code context - **User** section — `id`, `email`, `username` from `setUser()` - **Tags** sidebar — `test_run: hello-world`, `team: platform` - **Breadcrumbs** tab — chronological trail of events before the error - **Additional Data** — custom context from `setContext()` 4. Use the search bar to filter: `test_run:hello-world` narrows to your test events 5. Confirm **Environment** matches your `SENTRY_ENVIRONMENT` value 6. Confirm **Release** matches your `SENTRY_RELEASE` value (if set) 7. Delete test issues when done: select issues > **Resolve** or **Delete** ## Examples ### Complete Verification Script (TypeScript) Save as `test-sentry.mjs` and run with `node --import ./instrument.mjs test-sentry.mjs` to exercise all capabilities at once. ```typescript // Run with: node --import ./instrument.mjs test-sentry.mjs import * as Sentry from '@sentry/node'; async function main() { console.log('--- Sentry Hello World Verification ---\n'); // 1. Verify SDK const client = Sentry.getClient(); if (!client) { console.error('ERROR: Sentry SDK not initialized.'); console.error('Run with: node --import ./instrument.mjs test-sentry.mjs'); process.exit(1); } console.log('[OK] Sentry SDK active'); // 2. Set user context and tags Sentry.setUser({ id: 'test-001', email: 'dev@example.com', username: 'developer' }); Sentry.setTag('test_run', 'hello-world'); Sentry.setTag('environment', process.env.SENTRY_ENVIRONMENT || 'test'); console.log('[OK] User context and tags set'); // 3. Capture a message const msgId = Sentry.captureMessage('Hello Sentry — SDK verification', 'info'); console.log(`[OK] Message captured — Event ID: ${msgId}`); // 4. Capture an exception with breadcrumbs Sentry.addBreadcrumb({ category: 'test', message: 'Starting verification script', level: 'info' }); Sentry.addBreadcrumb({ category: 'test', message: 'About to throw test error', level: 'warning' }); try { throw new Error('Hello Sentry! Verification test exception.'); } catch (error) { const errId = Sentry.captureException(error); console.log(`[OK] Exception captured — Event ID: ${errId}`); } // 5. Flush and report await Sentry.flush(5000); console.log('\n[DONE] All events flushed — check your Sentry dashboard at https://sentry.io'); console.log('Navigate to Issues tab, filter by tag: test_run:hello-world'); } main(); ``` ### Complete Verification Script (Python) Save as `test_sentry.py` and run with `python test_sentry.py` (after calling `sentry_sdk.init()` in your setup). ```python # Run with: python test_sentry.py (after sentry_sdk.init() in your setup) import sentry_sdk import os import sys def main(): print("--- Sentry Hello World Verification ---\n") # 1. Verify SDK client = sentry_sdk.Hub.current.client if client is None or client.dsn is None: print("ERROR: Sentry SDK not initialized.") print("Ensure sentry_sdk.init(dsn=...) is called before this script.") sys.exit(1) print("[OK] Sentry SDK active") # 2. Set user context and tags sentry_sdk.set_user({"id": "test-001", "email": "dev@example.com", "username": "developer"}) sentry_sdk.set_tag("test_run", "hello-world") sentry_sdk.set_tag("environment", os.environ.get("SENTRY_ENVIRONMENT", "test")) print("[OK] User context and tags set") # 3. Capture a message msg_id = sentry_sdk.capture_message("Hello Sentry — SDK verification", level="info") print(f"[OK] Message captured — Event ID: {msg_id}") # 4. Capture an exception with breadcrumbs sentry_sdk.add_breadcrumb(category="test", message="Starting verification script", level="info") sentry_sdk.add_breadcrumb(category="test", message="About to throw test error", level="warning") try: raise ValueError("Hello Sentry! Verification test exception.") except Exception as e: err_id = sentry_sdk.capture_exception(e) print(f"[OK] Exception captured — Event ID: {err_id}") # 5. Flush and report sentry_sdk.flush() print("\n[DONE] All events flushed — check your Sentry dashboard at https://sentry.io") print("Navigate to Issues tab, filter by tag: test_run:hello-world") if __name__ == "__main__": main() ``` ## Output - Test message visible in Sentry dashboard Issues tab within 30 seconds - Test exception visible with full stack trace pointing to correct file and line - User context (`id`, `email`, `username`) attached to every event - Tags (`test_run`, `team`) searchable in the Issues sidebar filter - Breadcrumb trail visible in event detail, showing events leading up to the error - Custom context visible under "Additional Data" in event detail - Event IDs printed to console for cross-referencing with dashboard ## Error Handling | Error | Cause | Solution | |-------|-------|----------| | Event not appearing in dashboard | DSN misconfigured or env var not loaded | Run `echo $SENTRY_DSN` to verify; re-copy from Project Settings > Client Keys | | `getClient()` returns `undefined` | SDK not initialized before test code runs | Use `node --import ./instrument.mjs` flag or import instrument at top of entry | | Missing stack trace on exception | Error captured as string instead of Error object | Always pass `new Error('...')` to `captureException`, never a bare string | | No user context on event | `setUser()` called after `captureException()` | Call `setUser()` before any capture calls | | Events delayed > 60 seconds | Network or proxy blocking `*.ingest.sentry.io` | Check firewall rules; test with `curl https://sentry.io/api/0/` | | `Sentry Logger [warn]: Too many requests` | Rate limited by Sentry ingest | Lower `tracesSampleRate` in init; check quota at Settings > Subscription | | `flush()` times out | Large event queue or slow network | Increase timeout: `Sentry.flush(10000)`; check network latency | | Breadcrumbs not appearing | Max breadcrumbs exceeded (default 100) | Configure `maxBreadcrumbs` in `Sentry.init()` or clear with `Sentry.getCurrentScope().clearBreadcrumbs()` | ## Resources - [Capturing Errors — Node.js](https://docs.sentry.io/platforms/javascript/guides/node/usage/) - [Capturing Errors — Python](https://docs.sentry.io/platforms/python/usage/) - [Enriching Events — Context, Tags, User](https://docs.sentry.io/platforms/javascript/enriching-events/) - [Breadcrumbs Guide](https://docs.sentry.io/platforms/javascript/enriching-events/breadcrumbs/) - [Sentry Issue Search Syntax](https://docs.sentry.io/concepts/search/) ## Next Steps Proceed to `sentry-error-capture` for production error-handling patterns with scope isolation, custom fingerprinting, and error grouping strategies.