Atomic error handling is centered on:
Engine\Atomic\Core\ExceptionHandlerRegistrarEngine\Atomic\Core\ErrorHandlerEngine\Atomic\App\Error
ExceptionHandlerRegistrar::register($atomic) stores an ONERROR callback in the F3 hive.
Inside that callback the handler:
- reads the current
ERROR.*values from the hive - temporarily lowers
DEBUGfrom3+to2while handling the error - increments
ERROR.recursion_counter - formats the trace with
ErrorHandler::format_trace(...) - stores the formatted trace in
ERROR.formatted_trace - attempts to dump the hive with
Log::dumpHive() - stores
ERROR.dump_idandERROR.dump_pathwhen a dump was created - logs a structured
[ONERROR][code][level][status][text]message - selects the response mode based on request context
If ERROR.recursion_counter is already greater than 2, the handler aborts with:
Fatal error: too many error handler recursions
ErrorHandler::format_trace(int $code, string $text, string $trace): string
Behavior:
- starts output with the error text
- scans trace lines for
[...]segments containingfile:line - when the file is readable, includes a small source excerpt around the target line
- marks the target line with
>>>
If formatting itself throws, it returns a fallback string instead of propagating another exception.
Log::dumpHive() is conditional:
- dumps are only created when logger debug mode is enabled
- dump files go under the configured
DUMPSdirectory - if a dump is created, the dump id is appended to the structured log message
The error handler does not guarantee that every error will have a dump id.
A request is treated as API/AJAX when any of these are true:
AJAXis truthy- the path starts with
/api/ HTTP_ACCEPTcontainsapplication/json
Response shape:
{
"error": {
"status": "500 Internal Server Error",
"code": 500,
"text": "Internal Server Error",
"trace": null
}
}Important detail:
textis the real error text only when debug was enabled before the handler rantraceis included only when debug was enabled
500createsEngine\Atomic\App\Errorand callserror500(...)- other codes are matched against registered
/error/<code>routes and dispatched to a method likeerror404(...)when present - if the current path already starts with
/error/<code>, the handler avoids redispatching
- the handler writes the structured error message to CLI stderr through
CLI\Console\Output
Engine\Atomic\App\Error:
- boots the
ErrorPagestheme in its constructor - sets the HTTP status and relevant headers per method
- sets
PAGE.titleandPAGE.color - renders a layout such as
layout/404.atom.phporlayout/500.atom.php
For error500(...) specifically:
- if
ERROR.formatted_traceis empty, it setsNo trace available - if rendering the theme layout fails, it falls back to a minimal inline HTML page
Trigger an error through F3:
\Base::instance()->error(404, 'Resource not found');Once ONERROR has been registered, centralized handling runs automatically.
- Keep debug disabled in production if you do not want trace text in API responses.
- Ensure
LOGSand the derived dumps directory are writable if you rely on dump files. - Keep error templates available in the
ErrorPagestheme. - Do not assume dumps always exist for every error; they depend on logger debug mode.