본문으로 건너뛰기
cccskills
무료GitHub에 공개

error-capture

The frontend Error Inspector capture system (captureError, lib/diagnostics/**). Use when wiring a new CapturedErrorSource or adapter, calling captureError from a new site, picking a red/orange/yellow tier or errorTierRules downgrade, or turning a console.error or swallowed catch into a captured error.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md10.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Error Capture

<!-- rules:stamp -->

Rules from common-docs/systems/architecture/observability/error-surfaces/STATE.md — edit there, never here (python3 common-docs/meta/scripts/one_home.py --write).

  • Capture means a row with the inputs, the full traceback and the context that a human can read, acknowledge and dismiss. stderr, log.warning, print and a streamed event are not capture.
  • Extend record_error / system_error; never invent a per-feature error table or a second error tool. public.system_error is the one actionable incident queue; the specialized stores (app_log, system_write_failure, cx_tool_trace, ops_issue_event) stay.
  • Capture is best-effort: never raises, fresh connection, swallows its own failure (and screams to stdout).
  • Every paid or state-holding operation has an explicit except asyncio.CancelledError that records cost and state before re-raising; except Exception alone misses it. Detached DB writes use matrx_utils.detached_task, never asyncio.create_task inside a request.
  • Declare both source_app and source_feature on a captured error, or neither (the carried AppContext answers); SQL that inserts into ops.system_error names source_feature and uses the registered app database.
  • Group by a persistent fingerprint. The count is "since last cleared": resolve zeroes it, a recurrence after resolution reopens as one and links the prior incident. Fewer rows is the product; a count is a number on an existing row, never a new row on a human queue.
  • Every grouped row carries what it is, how many since cleared, and when it last happened; slight variances are kept (variants, variant_count); never merge genuinely distinct bugs to hit a smaller number.
  • One normalization law, server-side: clients consume the class token, never reimplement it.
  • Tool output is concise and redacted: rows never carry stacks or payloads, details cap each field and name the cut, and no secrets, cookies or signed URLs reach agent context.
  • Resolve only after the fix is deployed and the incident stays absent for its verification window; record the commit. Never resolve by suppressing a signal unless proven benign, with the reason recorded.
  • Retain all useful evidence, promote only actionable problems: uncaught exceptions, build or deploy failure, timeouts, OOM, dropped writes promote at once; successes, info logs, expected validation failures and health checks never queue.
  • The Fix-It Bar and the kind-problems reader are the human repair path and file no incidents; the GenericStructuredBlock alarm does.
<!-- rules:stamp-end -->

Read features/admin/error-inspector/FEATURE.md first — the architecture, the adapter list, and the invariants. This skill is the recipe; that doc is the map.

One sink, many adapters. Every error in the app funnels through captureError(input) (lib/diagnostics/errorCaptureStore.ts) into one module-level store the admin Error Inspector reads. Your job when adding a source: feed that one function — never stand up a parallel store, slice, or list.

Structured errors are the rule; generic browser noise is the fallback. Prefer capturing your own typed error (a stream event, an API body, a domain failure) with its real fields over relying on the console.error net.

The recipe — add a new captured source

  1. Add the source to the CapturedErrorSource union in lib/diagnostics/errorCaptureStore.ts, with a one-line doc comment. Name it for its origin (agent-stream-tool-error, media-durability, org-resolution).
  2. Add its label to SOURCE_LABELS in lib/diagnostics/buildCapturedErrorPayload.ts. This is Record<CapturedErrorSource, string> — forgetting it is a typecheck error, not a silent gap. That guardrail is the only thing forcing this step; honor it.
  3. Capture it. Call captureError({ source, message, ... }) from the one chokepoint every instance of this error flows through. Three shapes, pick the closest:
    • Inline at the site when there's a single loud-recovery point — mirror lib/organizations/personalOrg.ts (source: "org-resolution") or lib/media/durability.ts.
    • Extend an existing adapter when your error is a variant of one already handled — add a branch to captureStreamError.ts / captureApiError.ts.
    • A tiny new adapter in lib/diagnostics/ when it's a new class with its own plumbing — mirror captureApiError.ts (one file, one function, imported at the chokepoint).
  4. Tier it. Default is red. To make a whole source — or one signature — quieter, add a rule to DOWNGRADE_RULES in lib/diagnostics/errorTierRules.ts pointing at orange (dot) or yellow (silent). First match wins; put a specific relation/code rule ABOVE a broad source rule.
  5. Verify — pnpm type-check (catches the missing label), then a deterministic tsx check: feed your exact error shape through the adapter and assert getSnapshot() shows the right source/tier/fields. No live env needed.

Non-negotiables

  • Capture never breaks the caller. Wrap every captureError call in try { … } catch {}. It runs on hot paths and for all users (only the UI is admin-gated).
  • Capture is render-safe — calling it during render is legal, and emit() must stay async. The store defers listener notification to a microtask precisely so a loud-recovery scream inside render can't re-render the Inspector badge mid-render (React's "Cannot update a component while rendering a different component" — FOUND_DEFECTS D61/D76). Never make notification synchronous; lib/diagnostics/errorCaptureStore.renderSafety.test.tsx fails if you do. Corollary: a test asserting a subscriber saw a capture must await act(...) / flush microtasks first.
  • Preserve structured fields — don't flatten into raw. CaptureInput carries code, message, userMessage, details, hint, status, relation, requestId, conversationId, name, stack, callSite. Map the real fields; raw is the full dump on top, not instead.
  • userMessage is the server's human-facing text (distinct from technical message) — the seam for the future user-facing surface. Always set it when the source has one.
  • relation is the "what failed" label shown in lists — a table, tool:<name>, METHOD /path, a thunk name, an endpoint. Set it.
  • Tier is VISIBILITY, not log level. red = clear error (loud) · orange = minor (dot) · yellow = silent. A "warning" is just a source you tier orange/yellow — there is no separate warning concept.

Tiering judgment (current seeds, in errorTierRules.ts)

  • Real, unhandled failures → red (default): stream errors, Supabase, uncaught exceptions, react-render, org-resolution, api 5xx.
  • Handled / already-shown → orange: user-toast, redux-rejected (the slice rolled back).
  • Normal operation / by-design → yellow: agent-stream-tool-error (the agent tries a query, the guard rejects it, the agent adapts), aborted requests, total_timeout, ResizeObserver noise.
  • Match on source for a class; add code/relation/messageIncludes to a higher rule to carve out one signature. The admin tunes this live — "Copy for AI" embeds a paste-ready rule stub (buildDowngradeRuleStub).

Persistence (automatic)

A red-tier capture auto-persists (prod + authenticated, deduped, throttled) to the canonical public.system_error sink via the log_client_error RPC (lib/diagnostics/persistCapturedErrors.ts). So tier choice = persistence choice: a new red source lands in the server error dashboard for free; orange/ yellow stay client-only. No per-source wiring needed. Don't add a parallel persistence path — extend the RPC (migrations/log_client_error.sql) if a new field must reach the DB.

Every caller names its own app. log_client_error takes p_source_app, checked against a closed list (matrx-frontend, matrx-extend, matrx-local, matrx-mobile); an unknown value is a 400 with a sentence, and a caller that omits it hits a compatibility overload that assumes matrx-frontend. Adding a client app means adding it to that list in a migration. The RPC no longer swallows: a failed insert raises, and an error with no resolvable organization is still written with a note saying so (DD-115, migrations/log_client_error_source_app_and_loud_failures_dd115.sql).

And every caller names its FEATURE inside that app (2026-09-20, migrations/log_client_error_names_the_feature_too.sql). source_app / source_feature are ONE two-level categorization: the app, then the feature. The RPC's twelfth parameter is p_source_feature; this repo fills it from the route that failed via sourceFeatureForRoute (lib/diagnostics/errorSourceFeature.ts), so you do NOT pass it by hand — add a line to the map in that file when you ship a new top-level surface. A route the map does not cover records the registered sentinel client-unmapped, which is a visible to-do in the error dashboard, not a silent default. Slugs are a closed registry (SourceFeature in @ai-matrx/agents/generated/source-attribution); a new one is registered in aidream's source_attribution.py and the mirror regenerated, never invented here.

React boundaries

New error boundary → use lib/error-boundary/ErrorBoundaryWithCapture.tsx (capture built-in). Migrating a bespoke componentDidCatch → add one line: captureReactRenderError(error, { boundary, relation, componentStack }) (lib/diagnostics/captureReactError.ts). Route error.tsx boundaries are already covered at components/errors/ErrorBoundaryView.tsx — don't re-wire each one.

After you ship

Update features/admin/error-inspector/FEATURE.md: add your adapter to the list and a dated Change Log line.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Admin debug system wiring for the floating AdminIndicator's live debug data and Copy Full Context. Use when adding debug visibility to a route or feature, wiring useDebugContext or the debug panel, capturing console errors, or enabling the copy-context workflow for a page.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

Compact two-icon Copy / Copy-for-AI controls (components/agent-copy). Use when adding copy buttons to a row, card, list, or record; merging duplicate Copy/JSON/AI controls; continuing the copy rollout; or writing a Copy-for-AI payload. NOT for markdown content actions (use rich-document-actions).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

Disclosing a surface's existing fixed AI jobs in the shell's top Agents menu. Use when a page, panel, overlay, or window already runs a mandate behind a button, assist, automatic action, or mode; when the agent-disclosure guard names a file; or during a surface check.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

The watch-fix-rerun method for making an existing platform agent or automated process efficient and correct: baseline its ledger, run one unit yourself, fix the class behind every wasted call, rerun, record. Use when asked to improve, optimize, watch, or 'make efficient' an agent, a sandbox session, a sync job, or any recurring automated process.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

Redux state for agent execution and firing agent shortcuts. Use when editing features/agents/redux/, building agent UI, creating a conversation, touching assembleRequest or NDJSON stream state, wiring agent-state selectors, adding a per-conversation capability, or triggering a shortcut from a button, menu, or code (useShortcutTrigger, launchAgentExecution).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

The provision for a call site: the exhaustive menu of values that place in the code can realistically produce. Use before creating or fixing a mandate or agent that reasons about more than its own input, when deciding whether an agent can answer at all with what it is sent, or when its output 'looks right' but nobody checked it could be. NOT for building the agent (use create-agent).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 20일 업데이트

armanisadeghi의 스킬 모두 보기

이 스킬의 문제 신고