error-handling-patterns

Error Handling Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "error-handling-patterns" with this command: npx skills add thapaliyabikendra/ai-artifacts/thapaliyabikendra-ai-artifacts-error-handling-patterns

Error Handling Patterns

Build resilient applications with robust error handling strategies.

Error Handling Philosophies

Approach Use When

Exceptions Unexpected errors, exceptional conditions

Result Types Expected errors, validation failures

Error Codes C-style APIs, legacy integration

.NET Exception Patterns

Custom Exception Hierarchy

public class ApplicationException : Exception { public string Code { get; } public ApplicationException(string message, string code) : base(message) { Code = code; } }

public class ValidationException : ApplicationException { public ValidationException(string message) : base(message, "VALIDATION_ERROR") { } }

public class NotFoundException : ApplicationException { public NotFoundException(string resource, Guid id) : base($"{resource} not found: {id}", "NOT_FOUND") { } }

ABP BusinessException

// Use ABP's BusinessException for domain errors throw new BusinessException( code: ClinicManagementSystemDomainErrorCodes.PatientNotFound, message: "Patient not found") .WithData("PatientId", patientId);

Result Type Pattern

type Result<T, E = Error> = | { ok: true; value: T } | { ok: false; error: E };

function Ok<T>(value: T): Result<T, never> { return { ok: true, value }; }

function Err<E>(error: E): Result<never, E> { return { ok: false, error }; }

// Usage function parseJSON<T>(json: string): Result<T, SyntaxError> { try { return Ok(JSON.parse(json) as T); } catch (error) { return Err(error as SyntaxError); } }

.NET Resilience with Polly

HTTP Retry with Exponential Backoff

public IAsyncPolicy<HttpResponseMessage> BuildHttpRetryPolicy(int retryCount = 3) { return HttpPolicyExtensions .HandleTransientHttpError() .Or<TimeoutException>() .WaitAndRetryAsync( retryCount: retryCount, sleepDurationProvider: retryAttempt => { var exponentialDelay = TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)); var jitter = TimeSpan.FromMilliseconds(Random.Shared.Next(0, 1000)); return exponentialDelay + jitter; }, onRetryAsync: async (outcome, timespan, retryAttempt, context) => { _logger.LogWarning( "[Retry {Attempt}/{Total}] Waiting: {Delay:F2}s", retryAttempt, retryCount, timespan.TotalSeconds); }); }

Database Retry for Transient Errors

public IAsyncPolicy BuildDatabaseRetryPolicy(int retryCount = 3) { return Policy .Handle<DbUpdateConcurrencyException>() .Or<DbUpdateException>(ex => ex.InnerException is NpgsqlException npgsqlEx && IsTransientPostgresException(npgsqlEx)) .WaitAndRetryAsync( retryCount: retryCount, sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); }

private static bool IsTransientPostgresException(NpgsqlException ex) { var transientCodes = new[] { "40001", "40P01", "55P03", "57014", "53300", "08000" }; return transientCodes.Contains(ex.SqlState); }

Combined Policy (Retry + Circuit Breaker + Timeout)

public IAsyncPolicy<HttpResponseMessage> BuildResilientPolicy() { var timeout = Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(30));

var retry = HttpPolicyExtensions
    .HandleTransientHttpError()
    .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

var circuitBreaker = HttpPolicyExtensions
    .HandleTransientHttpError()
    .CircuitBreakerAsync(
        handledEventsAllowedBeforeBreaking: 5,
        durationOfBreak: TimeSpan.FromSeconds(30));

return Policy.WrapAsync(timeout, retry, circuitBreaker);

}

DI Registration

services.AddHttpClient<IMyApiClient, MyApiClient>() .AddPolicyHandler((provider, _) => { var retryService = provider.GetRequiredService<IRetryPolicyService>(); return retryService.BuildHttpRetryPolicy(); });

Circuit Breaker Pattern

States: CLOSED → Normal operation, tracking failures OPEN → Failing, reject all requests HALF_OPEN → Testing recovery with limited requests

Flow: CLOSED --[failure threshold]--> OPEN OPEN --[timeout]--> HALF_OPEN HALF_OPEN --[success]--> CLOSED HALF_OPEN --[failure]--> OPEN

Graceful Degradation

// Polly Fallback Policy public IAsyncPolicy<T> BuildFallbackPolicy<T>(Func<Task<T>> fallbackAction) { return Policy<T> .Handle<Exception>() .FallbackAsync( fallbackAction: async (context, cancellationToken) => { _logger.LogWarning("Primary operation failed, using fallback"); return await fallbackAction(); }, onFallbackAsync: async (exception, context) => { _logger.LogError(exception.Exception, "Fallback triggered"); }); }

// Usage var fallbackPolicy = BuildFallbackPolicy(() => FetchFromDatabaseAsync(userId)); var profile = await fallbackPolicy.ExecuteAsync(() => FetchFromCacheAsync(userId));

When to Retry

✅ Retry for:

  • HTTP API calls (transient network errors)

  • Database operations (deadlocks, connection timeouts)

  • External service integrations

  • File I/O operations

❌ Don't retry:

  • Authentication failures

  • Validation errors

  • Business logic errors

  • Non-idempotent operations without safeguards

Best Practices

  • Fail Fast - Validate input early

  • Preserve Context - Include stack traces, metadata

  • Meaningful Messages - Explain what and how to fix

  • Log Appropriately - Error = log, expected = don't spam

  • Handle at Right Level - Catch where you can meaningfully handle

  • Clean Up Resources - Use try-finally, using statements

  • Don't Swallow Errors - Log or re-throw, don't ignore

  • Type-Safe Errors - Use typed errors when possible

Detailed References

For comprehensive patterns, see:

  • references/exception-hierarchy-design.md

  • references/polly-advanced-patterns.md

  • references/async-error-handling.md

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

abp-infrastructure-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

abp-entity-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

abp-api-implementation

No summary provided by upstream source.

Repository SourceNeeds Review