darkwood/ia-exception-bundle

Augments HTTP 500 errors with AI-based exception analysis using Symfony AI

Installs: 19

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

Language:Twig

Type:symfony-bundle

pkg:composer/darkwood/ia-exception-bundle

v1.0.1 2026-02-08 22:17 UTC

This package is auto-updated.

Last update: 2026-02-08 22:19:10 UTC


README

Darkwood IA exception error page

Augments HTTP 500 errors with AI-based exception analysis using Symfony AI. Instead of a raw stack trace, you get a clear explanation, probable causes, and suggested fixes—generated by an LLM.

Requirements

  • PHP 8.2+
  • Symfony 6.4+, 7.x or 8.x
  • symfony/ai-bundle (with a configured platform and agent)

Installation

composer require darkwood/ia-exception-bundle

Register the bundle in config/bundles.php (if not auto-registered):

return [
    // ...
    Darkwood\IaExceptionBundle\DarkwoodIaExceptionBundle::class => ['all' => true],
];

Configure Symfony AI (e.g. OpenAI):

# config/packages/ai.yaml
ai:
  platform:
    openai:
      api_key: '%env(OPENAI_API_KEY)%'
  agent:
    default:
      model: 'gpt-4o-mini'

Configuration

# config/packages/darkwood_ia_exception.yaml
darkwood_ia_exception:
  enabled: true                  # Opt-in; set true only when appropriate
  only_status_codes: [500]       # HTTP codes to augment
  agent: 'ai.agent.default'      # AI agent service ID
  timeout_ms: 800                # Target timeout (enforce via AI platform http_client)
  cache_ttl: 600                 # Cache TTL in seconds (0 = disabled)
  cache: 'cache.app'             # PSR-6 cache service
  include_trace: false           # Dev only; never true in production

Enforcing Timeout

To enforce the timeout at the HTTP level, configure a scoped HTTP client for your AI platform:

# config/packages/ai.yaml
framework:
  http_client:
    scoped_clients:
      ai.timeout_client:
        base_uri: 'https://api.openai.com'
        timeout: 0.8  # 800ms

ai:
  platform:
    openai:
      api_key: '%env(OPENAI_API_KEY)%'
      http_client: 'ai.timeout_client'

Output Formats

JSON (Accept: application/json)

Returns a structured JSON response:

{
  "error_id": "a1b2c3d4e5f6g7h8",
  "english_exception": "The database connection failed or a required table is missing.",
  "probable_causes": [
    "MySQL server is down or unreachable",
    "Database credentials are incorrect",
    "The specified database or table does not exist"
  ],
  "suggested_fixes": [
    "Verify the database server is running",
    "Check DB_HOST, DB_USER, DB_PASS, and DB_NAME in .env",
    "Run migrations if the schema is out of date"
  ],
  "confidence": 0.85
}

HTML (default)

The HTML template shows:

  • Error ID
  • AI-generated explanation
  • Probable causes
  • Suggested next steps
  • Confidence score
  • Original exception class and message
  • Disclaimer that results are hypotheses

Security Considerations

  • Never send secrets to the AI. The bundle sends only:
    • Exception class, message, file, line
    • Optionally: stack trace (when include_trace: true)
  • No environment variables, cookies, headers, or request payloads are ever sent.
  • include_trace should be true only in dev; traces can reveal paths and structure.
  • Use in production only with sanitized input (exception context) and after reviewing your exception messages for sensitive data.

Reliability

  • Fail-safe: If the AI fails, times out, or throws any error, the bundle does not set a response. Symfony’s default 500 handling runs as usual.
  • 500 is always returned: The response status remains 500; the bundle only augments the body.
  • Caching: Results are cached by a fingerprint (exception class, message, top frames hash) with configurable TTL to limit cost and repetition.

License

MIT - Mathieu Ledru 2026