Exceptions & error handling

Pionia routes every uncaught throwable through ExceptionPipeline. Switches and the HTTP kernel do not use ad-hoc try/catch for normal errors — register behavior once at bootstrap.

Default behavior

ExceptionTypical HTTP statusClient message
ValidationException422Field message (e.g. missing required column)
ResourceNotFoundException404Not found message
HttpException subclassesAs set on exceptionMessage or generic text
Other Throwable500Hidden in production; details when DEBUG=true

GenericService create / update throws Pionia\Exceptions\ValidationException when a required field is missing.

Configure in a provider

// bootstrap/providers/AppProvider.php (example)
public function configureExceptions(\Pionia\Exceptions\ExceptionPipeline $pipeline): void
{
    $pipeline
        ->handler(\Application\ExceptionHandler::class) // optional custom renderer
        ->dontReport(\Pionia\Exceptions\ValidationException::class)
        ->map(\Pionia\Exceptions\ResourceNotFoundException::class, fn ($e) => response(404, $e->getMessage()));
}
MethodPurpose
handler()Replace the default renderer
reportable(callable)Sentry, Slack, extra logging
dontReport(class)Skip logging for expected client errors
map(class, callable)Return a custom Response before the default handler

Helpers

// Log without building a response
report($throwable);

// Full pipeline: report + render
$response = pionia_handle_exception($e, $request);

Use logger() for normal application logs; use report() when something failed but you are handling it elsewhere.

Self-rendering domain errors

Implement Pionia\Contracts\RenderableException (or extend HttpException) to control the HTTP response:

use Pionia\Contracts\RenderableException;
use Pionia\Http\Request\Request;
use Pionia\Http\Response\Response;

final class InsufficientCreditsException extends \RuntimeException implements RenderableException
{
    public function render(Request $request): Response
    {
        return Response::json(json_encode([
            'returnCode' => 402,
            'returnMessage' => $this->getMessage(),
            'returnData' => null,
        ]), 402);
    }
}

Debug JSON shape

When DEBUG=true or APP_DEBUG=true, API errors may include returnData with exception, file, line, and optional trace (controlled by [exceptions] RENDER_TRACES in settings.ini). In production, generic errors return An unexpected error occurred. without leaking internals.

Services and actions

In custom Service actions, throw ValidationException for client mistakes and HttpException for auth/domain errors. Avoid catching and swallowing errors in switches — let the pipeline handle them.

Related: Validations · Requests & responses · Database transactions.