ReviewRouter implements robust error handling to ensure reliability:
- Graceful degradation: Continue with partial results when providers fail
- Automatic retries: Retry transient failures with exponential backoff
- Provider fallbacks: Use backup providers when primary fails
- Budget protection: Stop execution before exceeding cost limits
- Detailed logging: Track errors for debugging and monitoring
All external API calls use automatic retry with exponential backoff:
import { withRetry } from '../utils/retry';
// Retry up to 3 times with exponential backoff
const result = await withRetry(
() => provider.review(prompt, timeout),
{
retries: 3,
minTimeout: 1000,
maxTimeout: 5000
}
);When retries are used:
- GitHub API calls (posting comments, fetching PR data)
- LLM provider structured-output failures, such as invalid review JSON
- File system operations (cache reads/writes)
Retry configuration:
- PROVIDER_RETRIES: 3 # Total attempts per provider for invalid review JSONWhen providers fail, the system continues with partial results:
// Provider execution with error handling
const results = await Promise.allSettled(
providers.map(p => p.review(prompt))
);
// Process successful results, log failures
const successful = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);Behavior:
- Minimum 1 successful provider required for review
- Failed providers logged in review summary
- Consensus engine adjusts for missing providers
- Synthesis continues with available results
Configure fallback providers for resilience:
REVIEW_PROVIDERS: openrouter/google/gemini-2.0-flash-exp:free
FALLBACK_PROVIDERS: openrouter/mistralai/devstral-2512:freeFallback triggers:
- Primary provider rate limited
- Primary provider timeout
- Primary provider API error
- Primary provider returns invalid response
Hard budget limits prevent runaway costs:
// Check budget before each provider call
if (costTracker.getTotalCost() > config.budgetMaxUsd) {
throw new Error(`Budget exceeded: ${costTracker.getTotalCost()} > ${config.budgetMaxUsd}`);
}Configuration:
- BUDGET_MAX_USD: 0.50 # Halt at $0.50Behavior:
- Check before each provider execution
- Halt immediately when exceeded
- Return partial results
- Log budget status
All operations have timeout protection:
- RUN_TIMEOUT_SECONDS: 300 # Total review timeout (5 min)
- PROVIDER_TIMEOUT_MS: 30000 # Per-provider timeout (30s)
- GRAPH_TIMEOUT_SECONDS: 10 # Graph analysis timeoutTimeout behavior:
- Provider timeout: Mark as failed, continue with others
- Total timeout: Return partial review with warning
- Graph timeout: Skip graph analysis, continue review
Validate all configuration and inputs:
// Configuration validation
if (config.providerLimit < 0) {
throw new Error('Provider limit must be non-negative');
}
// Input sanitization
const sanitizedDiff = diff.substring(0, config.diffMaxBytes);Validations:
- PR number is positive integer
- Provider names are valid
- File paths are safe (no path traversal)
- Budget limits are reasonable
- Timeouts are positive
Use structured logging for debugging:
import { logger } from '../utils/logger';
// Error logging with context
logger.error('Provider execution failed', {
provider: provider.name,
error: error.message,
duration: durationSeconds,
prNumber: pr.number,
});Log levels:
- ERROR: Failures that affect functionality
- WARN: Recoverable errors, retries, degraded mode
- INFO: Normal operation, progress updates
- DEBUG: Detailed execution traces
Configuration:
- LOG_LEVEL: info # Set to 'debug' for troubleshootingSymptoms:
429 Too Many Requestserrors- Providers marked as rate-limited in summary
- Review completes with fewer providers
Solutions:
-
Reduce parallel providers:
- PROVIDER_MAX_PARALLEL: 2 # Slower execution, less rate limiting
-
Use fallback providers:
FALLBACK_PROVIDERS: alternative/provider
-
Upgrade API tier: Get higher rate limits from provider
-
Spread load: Use provider rotation across PRs
Symptoms:
- Providers marked as timeout in summary
- Slow review execution
- Missing findings from specific providers
Solutions:
-
Increase timeout:
- PROVIDER_TIMEOUT_MS: 60000 # 60 seconds
-
Use faster providers:
- Check provider latency in analytics
- Replace slow providers
-
Reduce diff size:
- MAX_CHANGED_FILES: 50 # Skip very large PRs
Symptoms:
- Failed to post comments
- PR data fetch failures
- 403 Forbidden, 404 Not Found errors
Solutions:
-
Check permissions:
- Ensure
GITHUB_TOKENhas write access - Verify repository permissions
- Ensure
-
Fork PRs: External contributors need special handling
- SKIP_LABELS: external # Skip untrusted PRs
-
Retry configuration:
- PROVIDER_RETRIES: 3 # Total attempts for structured-output failures
Symptoms:
- Incremental review failures
- Invalid cached data errors
- Inconsistent review results
Solutions:
-
Clear cache:
rm -rf .mpr-cache/
-
Disable incremental temporarily:
- INCREMENTAL_ENABLED: false
-
Reduce cache TTL:
- INCREMENTAL_CACHE_TTL_DAYS: 3
Symptoms:
- AST analysis failures
- Unsupported file types
- Parsing timeout errors
Solutions:
-
Graceful fallback: AST failures don't block review
- Review continues with LLM-only analysis
- Missing AST evidence noted in findings
-
Disable AST for problematic files:
- ENABLE_AST_ANALYSIS: false
-
Report unsupported languages: File an issue for new language support
Symptoms:
- Node heap out of memory
- Action killed by runner
- Incomplete reviews for large PRs
Solutions:
-
Limit PR size:
- MAX_CHANGED_FILES: 100 - MAX_CHANGED_LINES: 2000
-
Disable heavy features:
- GRAPH_ENABLED: false - ENABLE_AST_ANALYSIS: false
-
Increase memory (self-hosted):
# docker-compose.yml deploy: resources: limits: memory: 4096M # 4GB
The system automatically recovers from:
- Transient network errors: Retry with backoff
- Provider failures: Use fallbacks or continue with others
- Rate limiting: Exponential backoff + fallbacks
- Cache misses: Fallback to full review
For persistent errors:
-
Check logs:
# GitHub Actions gh run view <run-id> --log # Self-hosted docker logs mpr-review
-
Retry failed PR:
# Re-run GitHub Action gh run rerun <run-id> # Or push empty commit to trigger new run git commit --allow-empty -m "Retry review" git push
-
Adjust configuration:
- Lower limits (files, cost, timeout)
- Disable features (AST, graph, test hints)
- Change providers
-
Dry run for debugging:
- DRY_RUN: true - LOG_LEVEL: debug
-
Provider success rate:
mpr analytics summary
- Should be >95%
- <90% indicates reliability issues
-
Average review duration:
- Should be <30s for typical PRs
-
60s indicates performance issues
-
Cache hit rate:
- Should be >60% with incremental reviews
- <40% indicates cache issues
-
Cost per review:
- Should match expected provider costs
- Spikes indicate efficiency issues
For production deployments, monitor:
# Example: Send alert if provider success rate drops
if (successRate < 0.90) {
sendAlert('Provider reliability degraded');
}
# Example: Alert on high costs
if (costPerReview > expectedCost * 2) {
sendAlert('Review costs unexpectedly high');
}- Always use retry wrapper for external calls
- Log errors with context (PR number, file, provider)
- Fail gracefully - partial results better than no results
- Validate inputs before processing
- Test error paths - ensure degradation works
- Use timeouts on all async operations
- Check budgets before expensive operations
- Set reasonable budgets to prevent cost overruns
- Monitor analytics for early warning of issues
- Test configuration with dry-run first
- Keep logs accessible for troubleshooting
- Report issues with full context (logs, config, PR)
- Use fallback providers for critical workflows
- Document custom error handling in your workflows
- LOG_LEVEL: debug- DRY_RUN: true# Disable features to isolate issues
- ENABLE_AST_ANALYSIS: false # Test without AST
- ENABLE_SECURITY: false # Test without security scanning
- GRAPH_ENABLED: false # Test without graph analysis# Use single provider to isolate provider-specific issues
REVIEW_PROVIDERS: openrouter/google/gemini-2.0-flash-exp:free
FALLBACK_PROVIDERS: ""# Run CLI locally to avoid GitHub Action overhead
mpr review --dry-run- Troubleshooting Guide - Common issues and fixes
- Performance Guide - Optimization strategies
- User Guide - Configuration and usage
- Analytics Guide - Cost and performance tracking