Error Resilience Expert logo

Error Resilience Expert

Community
roedyrustam
error-resilience-expert

Error resilience, circuit breakers, retries, and graceful degradation / Ketahanan error, circuit breaker, retry, dan degradasi anggun.

Overview

Publisherroedyrustam
Repositoryvibes-plug
Skill nameerror-resilience-expert
Stars
117
Forks
27
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by roedyrustam on GitHub. Read the source before you install it.

Installation

Install the Error Resilience Expert AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/roedyrustam/vibes-plug/tree/main/skills/error-resilience-expert
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/roedyrustam/vibes-plug.git /tmp/vibes-plug
mkdir -p .claude/skills
cp -r /tmp/vibes-plug/skills/error-resilience-expert .claude/skills/error-resilience-expert
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Error Resilience Expert in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Error Resilience Expert on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Error Resilience Expert is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Error & Resilience Expert (2026 Edition)

English | Bahasa Indonesia


English

Orchestration & Integration

  • Upstream Orchestrators: Works under brainstorming and zero-to-prod-orchestrator (Phase 6 - Production Hardening & Resilience) to ensure fault-tolerant application architectures.
  • Downstream Cooperating Skills:
    • logging-error-tracking-expert — Sentry/BugSnag integration and structured error logging.
    • data-telemetry-expert — Feed error rates and latency anomalies into circuit breakers.
    • js-backend-expert — API middleware error handling and RFC 9457 Problem Details formatting.
    • senior-frontend — React 19 Error Boundaries, suspense fallbacks, and resilient UI states.
    • database-orm-expert — Transaction retry strategies, deadlocks, and rollback policies.
    • async-queue-temporal-expert — Dead letter queues, retry backoffs, and durable saga recovery.
    • production-ready-hardener — Pre-launch failure mode verification and chaos testing.
    • session-memory-manager — Persist failure recovery logs and resilient state checkpoints.

Description

Production-grade guide for building resilient applications that fail gracefully, recover automatically, and provide actionable error feedback to users and developers. Covers React Error Boundaries, Next.js error handling (error.tsx, global-error.tsx, not-found.tsx), API error response standards (RFC 9457 Problem Details), retry patterns with exponential backoff, circuit breaker patterns, dead letter queues, and Sentry/BugSnag integration.

Trigger Conditions

Activate this skill when:

  • Setting up error handling for React/Next.js applications.
  • Implementing retry logic for unreliable API calls or third-party services.
  • Designing circuit breaker patterns for microservice-to-microservice calls.
  • Building fallback UI for degraded service states.
  • Integrating error tracking tools (Sentry, BugSnag, LogRocket).
  • Handling transaction failures in database operations.
  • Designing dead letter queues for failed async jobs.

Core Concepts

Error Handling Philosophy
PrincipleDescription
Fail FastDetect and report errors early; don't let invalid state propagate
Fail GracefullyShow useful fallback UI, not blank screens or raw stack traces
Retry IntelligentlyUse exponential backoff + jitter; never retry non-idempotent operations blindly
Isolate FailuresA failing component shouldn't crash the entire page
Track EverythingEvery unhandled error must reach your monitoring system

1. React & Next.js Error Handling

Error Boundaries (React 19)
tsx
// components/error-boundary.tsx
'use client';

import { Component, type ErrorInfo, type ReactNode } from 'react';

interface Props {
  children: ReactNode;
  fallback: ReactNode | ((error: Error, reset: () => void) => ReactNode);
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
}

interface State {
  hasError: boolean;
  error: Error | null;
}

export class ErrorBoundary extends Component<Props, State> {
  state: State = { hasError: false, error: null };

  static getDerivedStateFromError(error: Error): State {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    this.props.onError?.(error, errorInfo);
    // Report to Sentry/BugSnag
    if (typeof window !== 'undefined' && window.Sentry) {
      window.Sentry.captureException(error, { extra: errorInfo });
    }
  }

  reset = () => this.setState({ hasError: false, error: null });

  render() {
    if (this.state.hasError && this.state.error) {
      const { fallback } = this.props;
      return typeof fallback === 'function'
        ? fallback(this.state.error, this.reset)
        : fallback;
    }
    return this.props.children;
  }
}
Next.js App Router Error Files
tsx
// app/error.tsx — Route-level error handler
'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div role="alert" className="error-container">
      <h2>Something went wrong</h2>
      <p>{error.message}</p>
      {error.digest && <p className="text-muted">Error ID: {error.digest}</p>}
      <button onClick={reset}>Try again</button>
    </div>
  );
}

// app/not-found.tsx — 404 handler
export default function NotFound() {
  return (
    <div>
      <h2>Page Not Found</h2>
      <p>The page you are looking for does not exist.</p>
    </div>
  );
}

// app/global-error.tsx — Root layout error handler (catches layout errors)
'use client';

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={reset}>Try again</button>
      </body>
    </html>
  );
}

2. API Error Response Standards (RFC 9457)

typescript
// lib/api-error.ts
export class ApiError extends Error {
  constructor(
    public readonly status: number,
    public readonly code: string,
    message: string,
    public readonly details?: Record<string, unknown>,
  ) {
    super(message);
    this.name = 'ApiError';
  }

  /** RFC 9457 Problem Details JSON response */
  toJSON() {
    return {
      type: `https://api.example.com/errors/${this.code}`,
      title: this.code.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
      status: this.status,
      detail: this.message,
      ...(this.details && { extensions: this.details }),
    };
  }
}

// Usage in API route
export async function POST(request: Request) {
  try {
    const body = await request.json();
    const parsed = createUserSchema.safeParse(body);
    if (!parsed.success) {
      throw new ApiError(422, 'validation_error', 'Invalid request body', {
        errors: parsed.error.flatten().fieldErrors,
      });
    }
    const user = { id: 'usr_101', ...parsed.data };
    return Response.json(user, { status: 201 });
  } catch (error) {
    if (error instanceof ApiError) {
      return Response.json(error.toJSON(), { status: error.status });
    }
    // Unexpected error — log and return generic 500
    console.error('Unhandled error:', error);
    return Response.json(
      { type: 'about:blank', title: 'Internal Server Error', status: 500 },
      { status: 500 },
    );
  }
}

3. Retry Patterns with Exponential Backoff

typescript
// lib/retry.ts
interface RetryOptions {
  maxRetries?: number;
  baseDelayMs?: number;
  maxDelayMs?: number;
  /** Only retry if this returns true */
  retryIf?: (error: unknown) => boolean;
  onRetry?: (attempt: number, error: unknown) => void;
}

export async function withRetry<T>(
  fn: () => Promise<T>,
  options: RetryOptions = {},
): Promise<T> {
  const {
    maxRetries = 3,
    baseDelayMs = 500,
    maxDelayMs = 30_000,
    retryIf = isRetryable,
    onRetry,
  } = options;

  let lastError: unknown;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;

      if (attempt === maxRetries || !retryIf(error)) {
        throw error;
      }

      // Exponential backoff with jitter
      const delay = Math.min(
        baseDelayMs * 2 ** attempt + Math.random() * baseDelayMs,
        maxDelayMs,
      );

      onRetry?.(attempt + 1, error);
      await sleep(delay);
    }
  }

  throw lastError;
}

function isRetryable(error: unknown): boolean {
  if (error instanceof ApiError) {
    // Retry 429 (rate limit), 502/503/504 (server errors)
    return [429, 502, 503, 504].includes(error.status);
  }
  // Retry network errors
  if (error instanceof TypeError && error.message.includes('fetch')) return true;
  return false;
}

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

4. Circuit Breaker Pattern

typescript
// lib/circuit-breaker.ts
type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';

interface CircuitBreakerOptions {
  failureThreshold?: number;
  resetTimeoutMs?: number;
  halfOpenMaxAttempts?: number;
}

export class CircuitBreaker {
  private state: CircuitState = 'CLOSED';
  private failureCount = 0;
  private lastFailureTime = 0;
  private halfOpenAttempts = 0;

  constructor(
    private readonly name: string,
    private readonly options: CircuitBreakerOptions = {},
  ) {}

  private get failureThreshold() { return this.options.failureThreshold ?? 5; }
  private get resetTimeoutMs() { return this.options.resetTimeoutMs ?? 60_000; }

  async execute<T>(fn: () => Promise<T>): Promise<T> {
    if (this.state === 'OPEN') {
      if (Date.now() - this.lastFailureTime >= this.resetTimeoutMs) {
        this.state = 'HALF_OPEN';
        this.halfOpenAttempts = 0;
      } else {
        throw new Error(`Circuit breaker "${this.name}" is OPEN`);
      }
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  private onSuccess() {
    this.failureCount = 0;
    this.state = 'CLOSED';
  }

  private onFailure() {
    this.failureCount++;
    this.lastFailureTime = Date.now();
    if (this.failureCount >= this.failureThreshold) {
      this.state = 'OPEN';
    }
  }

  getState(): CircuitState { return this.state; }
}

// Usage
const paymentCircuit = new CircuitBreaker('stripe-api', {
  failureThreshold: 3,
  resetTimeoutMs: 30_000,
});

const charge = await paymentCircuit.execute(() =>
  stripe.paymentIntents.create({ amount: 1000, currency: 'usd' })
);

5. Graceful Degradation & Fallback UI

tsx
// components/resilient-data.tsx
'use client';

import { useSuspenseQuery } from '@tanstack/react-query';
import { Suspense } from 'react';
import { ErrorBoundary } from './error-boundary';

// Pattern: Wrap data-dependent UI with ErrorBoundary + Suspense
export function ResilientDataSection() {
  return (
    <ErrorBoundary
      fallback={(error, reset) => (
        <div className="degraded-state">
          <p>Unable to load latest data. Showing cached version.</p>
          <button onClick={reset}>Retry</button>
        </div>
      )}
    >
      <Suspense fallback={<DataSkeleton />}>
        <LiveDataSection />
      </Suspense>
    </ErrorBoundary>
  );
}

6. Dead Letter Queue for Failed Jobs

typescript
// queues/dead-letter.ts
import { Queue, Worker } from 'bullmq';

const mainQueue = new Queue('email-send', { connection: redis });
const deadLetterQueue = new Queue('email-send-dlq', { connection: redis });

const worker = new Worker('email-send', async (job) => {
  await sendEmail(job.data);
}, {
  connection: redis,
  settings: {
    backoffStrategy: (attemptsMade) => {
      // Exponential backoff: 1s, 4s, 16s, 64s
      return Math.min(1000 * 4 ** attemptsMade, 120_000);
    },
  },
});

worker.on('failed', async (job, err) => {
  if (job && job.attemptsMade >= (job.opts.attempts ?? 3)) {
    // Move to dead letter queue for manual investigation
    await deadLetterQueue.add('failed-email', {
      originalJobId: job.id,
      data: job.data,
      error: err.message,
      failedAt: new Date().toISOString(),
    });
  }
});

7. Chaos Engineering & Automated Failure Injection Protocol

  1. Chaos Injection: Actively test system resilience by simulating network disruptions, killing database connections, and injecting artificial latency (500ms–5000ms) or dropped packets using Toxiproxy or mock network middleware.
  2. Failure Observation: Monitor application behavior under duress. Check whether the UI hangs, returns blank screens, or if connections leak.
  3. Automated Resilience Hardening:
    • Implement Circuit Breakers around fragile external API dependencies.
    • Add exponential backoff with full jitter to avoid thundering herds.
    • Implement graceful degradation: render cached data or contextual fallback states rather than throwing unhandled exceptions.
  4. Resilience Verification: Re-run the disruption loop until all failure modes are safely caught, logged to Sentry, and recovered from automatically.

Common Pitfalls to Avoid

Anti-PatternProblemCorrect Approach
Catching errors silently (catch (e) {})Errors disappear, bugs hideAlways log or re-throw with context
Retrying non-idempotent operationsDuplicate charges, double insertsOnly retry reads and idempotent writes
No timeout on external callsThread/connection pool exhaustionSet AbortSignal.timeout() on all fetch calls
Generic "Something went wrong" for all errorsUsers can't self-resolveShow actionable messages (retry, contact support, check input)
Using try/catch around every single lineCode becomes unreadableUse error boundaries and middleware for batch handling

Sovereign Execution, Token Efficiency & Invariants

DimensionSovereign Mandate & Deterministic Contract
Frontier Model CascadeMedium / High (GPT-5.6 Sol Medium, Gemini 4 Argon, Claude Sonnet 5.5 High, Grok 4.7 High Fast)
Availability FallbackGemini 4 Argon/Pro -> Gemini 3.8 Flash; Claude Opus 5.5 -> Claude Opus 4.6 (Zero unhandled missing-model errors)
KV-Cache & Token ProtocolPin static instructions & schemas at prompt prefix (kv-cache-prefix-optimizer); pass surgical CONTEXT_MAP.md slices (<250 tokens/call) during Swarm Fan-Out
SaaT CLI & MCP DispatchCLI: vibes skill exec error-resilience-expert <audit|eval|verify|generate|blueprint> / MCP: vibes_skill_dispatch, vibes_ast_query, vibes_compile_cache, vibes_optimize_budget, vibes_verify_gate
NFR & Anti-Slop InvariantsP99 API Gateway Latency < 85ms, OpenAPI 3.1 / TypeSpec strict schema parity, RFC 9457 Problem Details error contracts, Idempotency-Key enforcement; 100% complete zero-placeholder output verified via node scripts/check-anti-slop.js --strict


Bahasa Indonesia

Integrasi Orkestrasi

  • Orkestrator Hulu: Beroperasi di bawah arahan brainstorming dan zero-to-prod-orchestrator (Fase 6 - Hardening Produksi & Ketahanan) untuk memastikan arsitektur aplikasi yang toleran terhadap kegagalan.
  • Skill Hilir & Kerja Sama:
    • logging-error-tracking-expert — Integrasi Sentry/BugSnag dan logging error terstruktur.
    • data-telemetry-expert — Menyalurkan tingkat error dan anomali latensi ke circuit breaker.
    • js-backend-expert — Middleware penanganan error API dan pemformatan RFC 9457 Problem Details.
    • senior-frontend — Error Boundary React 19, fallback suspense, dan UI state yang resilien.
    • database-orm-expert — Strategi retry transaksi, deadlock, dan kebijakan rollback.
    • async-queue-temporal-expert — Dead letter queue, backoff retry, dan pemulihan saga terdistribusi.
    • production-ready-hardener — Verifikasi mode kegagalan pra-peluncuran dan uji chaos.
    • session-memory-manager — Menyimpan log pemulihan kegagalan dan checkpoint status resilien.

Deskripsi

Panduan tingkat produksi untuk membangun aplikasi yang tahan banting — gagal secara anggun, pulih otomatis, dan memberikan umpan balik error yang dapat ditindaklanjuti kepada pengguna maupun developer. Mencakup React Error Boundaries, penanganan error Next.js (error.tsx, global-error.tsx, not-found.tsx), standar respons error API (RFC 9457 Problem Details), pola retry dengan exponential backoff, pola circuit breaker, dead letter queues, dan integrasi Sentry/BugSnag.

Kondisi Pemicu

Aktifkan skill ini ketika:

  • Menyiapkan penanganan error untuk aplikasi React/Next.js.
  • Mengimplementasikan logika retry untuk panggilan API yang tidak stabil atau layanan pihak ketiga.
  • Merancang pola circuit breaker untuk panggilan antar-microservice.
  • Membangun UI fallback untuk kondisi layanan terdegradasi.
  • Mengintegrasikan alat pelacak error (Sentry, BugSnag, LogRocket).
  • Menangani kegagalan transaksi pada operasi database.
  • Merancang dead letter queue untuk job asinkron yang gagal.

Konsep Inti

Filosofi Penanganan Error
PrinsipDeskripsi
Gagal CepatDeteksi dan laporkan error sedini mungkin; jangan biarkan state invalid menyebar
Gagal dengan AnggunTampilkan UI fallback yang berguna, bukan layar kosong atau stack trace mentah
Retry dengan CerdasGunakan exponential backoff + jitter; jangan retry operasi non-idempoten secara membabi buta
Isolasi KegagalanKomponen yang gagal tidak boleh menghancurkan seluruh halaman
Lacak SemuanyaSetiap error yang tidak tertangani harus sampai ke sistem monitoring

Protokol Chaos Engineering & Injeksi Kegagalan Otomatis

  1. Injeksi Kekacauan (Chaos Injection): Uji ketahanan dengan sengaja memutuskan koneksi database, menyuntikkan latensi jaringan (Toxiproxy), atau membuang paket request ke API eksternal.
  2. Observasi Kegagalan: Periksa apakah UI macet, layar menjadi putih kosong, atau connection pool bocor saat dependensi bermasalah.
  3. Hardening Ketahanan Otomatis:
    • Terapkan Circuit Breaker pada panggilan API eksternal yang rentan.
    • Tambahkan retry dengan exponential backoff dan random jitter.
    • Terapkan degradasi anggun (graceful degradation): sajikan data cache atau UI fallback alternatif.
  4. Verifikasi Ketahanan: Ulangi simulasi gangguan hingga sistem bertahan tanpa crash fatal dan seluruh error tercatat di Sentry.

Kesalahan Umum yang Harus Dihindari

Anti-PolaMasalahPendekatan yang Benar
Menangkap error diam-diam (catch (e) {})Error menghilang, bug tersembunyiSelalu log atau lempar ulang dengan konteks
Retry operasi non-idempotenCharge ganda, insert duplikatHanya retry operasi baca dan write idempoten
Tidak ada timeout pada panggilan eksternalThread/pool koneksi habisPasang AbortSignal.timeout() pada semua panggilan fetch
Pesan generik "Terjadi kesalahan" untuk semua errorPengguna tidak bisa menyelesaikan sendiriTampilkan pesan yang actionable (retry, hubungi support, periksa input)

Matriks Eksekusi Berdaulat, Efisiensi Token & Invarian

DimensiMandat Berdaulat & Kontrak Deterministik
Kaskade Model FrontierMedium / High (GPT-5.6 Sol Medium, Gemini 4 Argon, Claude Sonnet 5.5 High, Grok 4.7 High Fast)
Invarian Fallback KetersediaanGemini 4 Argon/Pro -> Gemini 3.8 Flash; Claude Opus 5.5 -> Claude Opus 4.6 (Bebas gagal saat model belum tersedia/kuota penuh)
Protokol Hemat Token & KV-CacheKunci instruksi & skema statis di prefix awal (kv-cache-prefix-optimizer); kirim potongan CONTEXT_MAP.md (<250 token/panggilan) saat Fan-Out
Eksekusi SaaT CLI & MCPCLI: vibes skill exec error-resilience-expert <audit|eval|verify|generate|blueprint> / MCP: vibes_skill_dispatch, vibes_ast_query, vibes_compile_cache, vibes_optimize_budget, vibes_verify_gate
Invarian NFR & Anti-SlopLatensi P99 API < 85ms, paritas skema ketat OpenAPI 3.1 / TypeSpec, kontrak error RFC 9457 Problem Details, penegakan Idempotency-Key; kode 100% tuntas tanpa placeholder diverifikasi melalui node scripts/check-anti-slop.js --strict

Frequently asked questions

What does the Error Resilience Expert AI skill do?

Error resilience, circuit breakers, retries, and graceful degradation / Ketahanan error, circuit breaker, retry, dan degradasi anggun.

Why use Error Resilience Expert on TypingMind?

Because you install it once and use it with any model. Error Resilience Expert is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Error Resilience Expert in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/roedyrustam/vibes-plug/tree/main/skills/error-resilience-expert. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Error Resilience Expert?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Error Resilience Expert?

As many as you like. As long as a model supports skills, you can use Error Resilience Expert with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Error Resilience Expert AI skill free?

Yes. It is published on GitHub by roedyrustam under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇