Skip to content

Troubleshooting and logging

When an example behaves differently from the guide, begin with the smallest failing request. Note its URL, method and HTTP status, then check the terminal running PHP or the web server log. If logs/app.log exists, look for the corresponding application message.

The tutorials include an "If the result is different" section beside their verification steps. Start there for a symptom specific to that example, then use the sections below to investigate further. Reproduce the failure locally with the same dependencies and configuration. Use APP_ENV=dev for detailed local errors and keep deployed applications on APP_ENV=prod.

A 400 or 422 response can be the expected rejection of invalid input. Compare it with the guide's valid request before changing configuration. For an API that hides exception details, read the server log rather than adding those details to the response.

Logging

The core binds Psr\Log\LoggerInterface to a file logger at logs/app.log under BASE_PATH. The runtime user needs write access. Naf\log() retrieves the registered logger; application services can receive it through constructor injection.

use function Naf\log;

log()->info('Import completed: {count} records', ['count' => 12]);
log()->error('Import failed: {reference}', ['reference' => $reference]);

Include context that helps locate the failure, without passwords, bearer tokens or sensitive request bodies. The default logger interpolates {key} placeholders; context fields without placeholders are not written separately. Use a PSR-3 implementation suited to your deployment for structured context, rotation or central collection. Bind it under LoggerInterface::class in bootstrap.php before consumers are constructed.

Routing and bootstrap

Symptom Check Action
Web-server 404 on all routes Document root and routing fallback Serve public/; forward nonexistent files to public/index.php
NAF 404 on one route Method and path Inspect vendor/bin/naf route:debug with CLI installed
Unknown named argument Placeholder and parameter names Match {id} to $id
Class not found Namespace, case and autoload mapping Check App\ maps to app/; run composer dump-autoload
Service missing while loading routes Resolution timing Register handlers in routes; resolve services after bootstrap bindings
get() cannot find a concrete class Service registration Use constructor injection or make() for autowiring

php bootstrap.php does not process HTTP. Under CLI, run() returns without routing or emission. Use a server and HTTP tests.

Plugins and configuration

Plugins must be installed Composer packages of type naf-plugin. A cloned sibling directory does not activate them. With CLI 0.2.3+, vendor/bin/naf plugins:debug shows resolved boot order and prerequisites. Use lazy factories for cross-plugin services. See Plugins.

For an ignored setting, check .env.local, the process environment, its colon-separated path and merge order. Numeric arrays replace positions. config() reads cached configuration; it is not a setter. env() returns the environment name, not an arbitrary variable. See Configuration.

Forms and sessions

Symptom Cause to check Action
CSRF token missing No token field/header Include _csrf or X-CSRF-Token and retain cookies
CSRF token invalid Replaced token or lost session Generate once per page; fetch a new form after token replacement
Undefined template helper Missing import Import from Naf\Form or Naf\View in that template
Input lost after redirect Request-only memory() Render validation errors in the current request or explicitly persist fields
Database sessions use files Missing Database plugin Inspect the warning, install/configure Database and migrate

See Forms and Sessions for exact behavior.

Background work and integrations

For scheduled jobs that do not execute, check the ticker, worker and selected channels. Inspect worker failures and deadletter storage before retrying. Check permissions, driver and lease duration. See Queues and Scheduling.

For mail, check the transport: PHP's mail() needs delivery configuration, while local capture intentionally writes no external mail. For HTTP calls, inspect exceptions, CA configuration and retries. HTTP 4xx/5xx responses must be inspected by the caller; transport failures raise exceptions. See Mail and HTTP client.