Errors and aborting¶
An unknown route, a thrown exception or abort() reaches the error-handling path.
The default response uses the exception's getStatusCode() when available, otherwise 500.
Abort a request¶
use function Naf\abort;
abort(404, 'The requested item was not found.');
abort() throws Naf\Exceptions\AbortException; it does not render a template or send a
response itself. Code after the call is not executed unless an outer layer catches the exception.
Avoid catching and discarding it inside a broad catch (Throwable).
Default output¶
The core supplies diagnostic and sanitized error templates. APP_ENV=prod and APP_ENV=test
use sanitized output; dev shows diagnostics. Use the exact names documented in
Configuration.
Placing app/views/errors/404.phtml in your application does not automatically override
the core error handler. To customize an error, return a response from the exception event.
Customize an HTTP error¶
Register this in bootstrap.php, after the autoloader and before app()->run():
use Naf\Core\{ErrorHandler, Event};
use function Naf\{event, response};
event()->listen(Event::EXCEPTION, function (\Throwable $exception) {
if (ErrorHandler::resolveStatusCode($exception) !== 404) {
return null; // Keep the default response for other failures.
}
return response('<h1>Page not found</h1>', 404, [
'Content-Type' => 'text/html; charset=UTF-8',
]);
});
With naf/view, you can instead return Naf\View\render('errors.404')->withStatus(404).
Pass any template data explicitly; no $path variable is injected automatically.
JSON errors for an API¶
For expected validation failures, return json($payload, 422) from your handler. To cover
uncaught exceptions as well, register this before app()->run():
use Naf\Core\{ErrorHandler, Event};
use function Naf\{event, json, log, request};
event()->listen(Event::EXCEPTION, function (\Throwable $exception) {
if (!str_starts_with(request()->getUri()->getPath(), '/api/')) {
return null;
}
log()->error('API request failed', ['exception' => $exception]);
$status = ErrorHandler::resolveStatusCode($exception);
return json(['error' => $status >= 500 ? 'Internal server error' : 'Request refused'], $status);
});
Do not expose unexpected exception messages to clients. When a listener returns its own response, it should also perform any logging you need. This hook handles failures during the request cycle; a parse error in the bootstrap itself may occur before the listener exists.