Middleware

Error Handling Middleware

Handle and log errors with virtually zero configuration in Kipchak.

Introduction

The Error Middleware intercepts unhandled exceptions and PHP errors within your application. It converts them into standardized, API-friendly JSON responses, ensuring that your API consumers never encounter raw HTML stack traces or silent failures.

Key features include:

  • Automated JSON Formatting: Catches all Throwables and returns a structured JSON payload.
  • Environment Awareness: Displays detailed stack traces when debug is enabled, and generic messages in production.
  • Logging Integration: Automatically logs exceptions to the built in logger (e.g., Monolog) based on your verbosity settings.

Installation

Install the middleware via composer by running:

composer require kipchak/middleware-error

Configuration

Unlike other middlewares, the Error Middleware typically relies on your global application configuration found in kipchak.api.php. It uses the global debug and logging flags to determine its behavior.

Configuration Keys

The below properties are configured in kipchak.api.php.

  • debug (bool):
    • true: The middleware will return detailed JSON responses including file, line, and trace. (Development mode).
    • false: The middleware returns a generic "Internal Server Error" message to prevent information leakage. (Production mode).
  • logExceptions (bool):
    • If true, exceptions are sent to the registered Logger instance.
  • logExceptionDetails (bool):
    • If true, the log entry will include the full stack trace.
  • logExceptionsTo (string, optional):
    • 'error_log' (the default): Slim writes exceptions with PHP's error_log(), as in earlier versions.
    • 'logger': exceptions go through the Logger driver instead, at error level, so they share your API's log format and pass through its processors, such as PII Redaction's. Without the Logger driver, error_log() is used. Requires kipchak/middleware-error 1.29 or later.

Example Configuration

<?php

use function Kipchak\Core\env;

return [
    // ... other settings ...
    'debug' => (bool) env('DEBUG', true),
    'logExceptions' => true,
    'logExceptionDetails' => true,
    // 'logExceptionsTo' => 'logger',
];

Usage

Initialise it twice in middlewares/middlewares.php, as the first and the last line, with every other global middleware between the two:

use Kipchak\Middleware\Error\Error;

Error::initialise($app);   // innermost: turns route exceptions into JSON responses
// ... every other global middleware
Error::initialise($app);   // outermost: does the same for exceptions from the middleware above

Slim runs the middleware added last first. The first is therefore the innermost middleware: it answers an exception thrown by a route, and the middleware around it, such as OpenTelemetry, Metering and Redaction, sees the JSON response. The last is the outermost: it answers an exception thrown by any other middleware, which would otherwise reach the client as a plain-text 500. See Middleware.

Response Formats

1. Production Response (debug => false)

When an error occurs in production, the details are suppressed.

{
    "message": "Internal Server Error",
    "exception": [
        {
            "type": "Exception",
            "code": 500,
            "message": "Internal Server Error",
            "file": "/path/to/app/src/Core/ErrorHandler.php",
            "line": 42
        }
    ]
}
// Note: The structure may vary slightly, but sensitive trace data is hidden.

2. Debug Response (debug => true)

In development, you get full visibility to debug issues quickly.

{
    "message": "Call to undefined function missing_function()",
    "exception": [
        {
            "type": "Error",
            "code": 500,
            "message": "Call to undefined function missing_function()",
            "file": "/var/www/html/src/Controllers/UserController.php",
            "line": 25,
            "trace": [
                "#0 /var/www/html/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(43): App\\Controllers\\UserController->__invoke(...)",
                "#1 ..."
            ]
        }
    ]
}

You'll see these in the container logs on a single line formatted as JSON .

Git Repository

The source code for this middleware is available on 1x.ax at https://1x.ax/mamluk/kipchak/middlewares/error.

Previous
Auth - Request Signing