create-dead-letter-queue
Dead Letter Queue Generator
Creates Dead Letter Queue pattern infrastructure for capturing and retrying failed messages.
When to Use
| Scenario | Example |
|---|---|
| Poison messages | Messages that always cause handler failures |
| Processing failures | Temporary infrastructure issues (DB down, timeout) |
| Audit trail | Track all failed message processing attempts |
| Retry mechanism | Automatic retry with exponential backoff |
| Monitoring | Alert on DLQ threshold exceeded |
Component Characteristics
DeadLetterMessage
- Entity capturing failed message details
- Original message body, headers, routing key
- Error message and stack trace
- Attempt count and timestamps
- Failure classification (Transient, Permanent, Unknown)
DeadLetterStoreInterface
- Application layer port
- store(DeadLetterMessage): void
- findRetryable(int limit): array — find messages eligible for retry
- markRetried(string id): void — increment attempt count
- markResolved(string id): void — mark as successfully reprocessed
- purge(DateTimeImmutable before): int — remove old entries
DeadLetterHandler
- Catches exceptions from message handlers
- Classifies failure type (transient vs permanent)
- Stores to DLQ with full context
- Logs failure details
RetryStrategy
- Configurable max attempts
- Exponential backoff with jitter
- Failure type classification
- Skip permanent failures
FailureClassifier
- Classifies exceptions as Transient or Permanent
- Configurable exception mapping
- Default: ConnectionException=Transient, ValidationException=Permanent
DlqProcessor
- Processes retryable messages from DLQ
- Applies RetryStrategy for backoff
- Removes successfully processed messages
- Re-stores still-failing messages
Generation Process
Step 1: Analyze Request
Determine:
- Storage backend (Database)
- Max retry attempts (default: 5)
- Backoff strategy (exponential with jitter)
Step 2: Generate Core Components
-
Domain Layer (
src/Domain/Shared/DeadLetter/)FailureType.php— Enum (Transient, Permanent, Unknown)DeadLetterMessage.php— Message entity
-
Application Layer (
src/Application/Shared/DeadLetter/)DeadLetterStoreInterface.php— Storage portDeadLetterHandler.php— Exception handlerRetryStrategy.php— Retry configuration and backoff calculationFailureClassifier.php— Exception classificationDlqProcessor.php— Retry processor
-
Infrastructure Layer (
src/Infrastructure/DeadLetter/)DatabaseDeadLetterStore.php— PDO implementation- Database migration
-
Tests
DeadLetterMessageTest.phpRetryStrategyTest.phpFailureClassifierTest.phpDlqProcessorTest.php
File Placement
| Layer | Path |
|---|---|
| Domain Types | src/Domain/Shared/DeadLetter/ |
| Application | src/Application/Shared/DeadLetter/ |
| Infrastructure | src/Infrastructure/DeadLetter/ |
| Unit Tests | tests/Unit/{Layer}/{Path}/ |
Key Principles
Failure Classification
- Transient: Connection errors, timeouts, rate limits — eligible for retry
- Permanent: Validation errors, business rule violations — never retry
- Unknown: Unclassified exceptions — retry with caution
Retry Strategy
- Max attempts configurable (default: 5)
- Exponential backoff: delay = baseDelay * 2^attempt
- Jitter: random ±25% to prevent thundering herd
- Skip messages exceeding max attempts
Message Lifecycle
Message → Handler fails → DeadLetterHandler → Store to DLQ
↓
DlqProcessor retries
↓
Success → Remove from DLQ
Failure → Re-store with incremented attempts
Max exceeded → Mark as permanently failed
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Failure Enum | FailureType |
FailureType |
| Message Entity | DeadLetterMessage |
DeadLetterMessage |
| Store Interface | DeadLetterStoreInterface |
DeadLetterStoreInterface |
| Handler | DeadLetterHandler |
DeadLetterHandler |
| Strategy | RetryStrategy |
RetryStrategy |
| Classifier | FailureClassifier |
FailureClassifier |
| Processor | DlqProcessor |
DlqProcessor |
| Test | {ClassName}Test |
RetryStrategyTest |
Quick Template Reference
DeadLetterMessage
final class DeadLetterMessage
{
public function __construct(
public readonly string $id,
public readonly string $originalBody,
public readonly string $originalRoutingKey,
public readonly array $originalHeaders,
public readonly string $errorMessage,
public readonly string $errorTrace,
public readonly FailureType $failureType,
public readonly int $attemptCount,
public readonly \DateTimeImmutable $failedAt,
public readonly ?\DateTimeImmutable $nextRetryAt,
public readonly ?\DateTimeImmutable $resolvedAt = null,
) {}
public function isRetryable(int $maxAttempts): bool;
public function withIncrementedAttempt(\DateTimeImmutable $nextRetryAt): self;
}
DeadLetterStoreInterface
interface DeadLetterStoreInterface
{
public function store(DeadLetterMessage $message): void;
/** @return array<DeadLetterMessage> */
public function findRetryable(int $limit = 100): array;
public function markRetried(string $id, \DateTimeImmutable $nextRetryAt): void;
public function markResolved(string $id): void;
public function purge(\DateTimeImmutable $before): int;
public function countByType(FailureType $type): int;
}
Database Schema
CREATE TABLE dead_letter_messages (
id VARCHAR(255) PRIMARY KEY,
original_body TEXT NOT NULL,
original_routing_key VARCHAR(255) NOT NULL,
original_headers JSONB NOT NULL DEFAULT '{}',
error_message TEXT NOT NULL,
error_trace TEXT,
failure_type VARCHAR(50) NOT NULL,
attempt_count INTEGER NOT NULL DEFAULT 1,
failed_at TIMESTAMP(6) NOT NULL,
next_retry_at TIMESTAMP(6),
resolved_at TIMESTAMP(6)
);
CREATE INDEX idx_dlq_retryable ON dead_letter_messages (failure_type, next_retry_at)
WHERE resolved_at IS NULL AND failure_type != 'permanent';
CREATE INDEX idx_dlq_failed_at ON dead_letter_messages (failed_at);
References
For complete PHP templates and test examples, see:
references/templates.md— All component templatesreferences/examples.md— Message broker integration example and unit tests
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12