Skip to content
Greg Bowler edited this page May 27, 2026 · 2 revisions

When a request fails, WebEngine tries to turn that failure into a useful HTTP response rather than leaving PHP to dump raw output at the browser.

Error types

Common error types include:

  • missing pages
  • application exceptions
  • validation and user-facing failures
  • configuration problems

Not all of these should be shown to the user in the same way, which is why WebEngine distinguishes them while handling the request.

Error rendering

WebEngine first tries to render an application-specific error page. If that fails too, it falls back to a simpler built-in error response.

Development and production should behave differently here. Development needs detail. Production needs safety and clarity.

Custom error pages

Custom error pages live in the directory configured by app.error_page_dir, which defaults to page/_error.

Create one HTML file per HTTP status code you want to handle, for example:

  • page/_error/404.html
  • page/_error/500.html
  • page/_error/403.html

When an exception resolves to one of those status codes, WebEngine will try to render the matching page. If no matching template exists, it falls back to the built-in error response.

In development mode, fallback 404 responses include a hint showing the missing error page path. In production mode, that extra detail is suppressed.

See Configuration reference#Config section: app for the error_page_dir setting.

Logging and diagnosis

Errors are logged as part of the request lifecycle. When diagnosing a problem, usually start by checking:

  • the request path
  • the matching page files
  • recent configuration changes
  • the application logs

Avoid leaking sensitive stack details to the browser in production responses.

Using the logger

The main logger settings live under the logger config section.

  • logger.level controls the minimum level for the main log stream.
  • logger.stderr_level controls when messages are duplicated to stderr.
  • logger.log_all_requests enables request logging for normal responses.
  • logger.log_redirects enables logging for redirect responses.
  • logger.log_404_to_error_log writes 404 responses to the error log.
  • logger.debug_to_javascript controls whether buffered debug output is exposed to browser-side JavaScript tooling.

To log a message in application code, import GT\Logger\Log and call the method matching the level you want:

use GT\Logger\Log;

Log::debug("Starting import");
Log::info("User signed in");
Log::notice("Request took longer than expected");
Log::warning("Configured fallback was used");
Log::error("Payment provider request failed");

You can also attach context data to the log entry:

use GT\Logger\Log;

Log::info("Order created", [
	"orderId" => 4821,
	"userId" => 19,
]);

Log::error("Database query failed", [
	"query" => "select * from invoice where id = ?",
	"invoiceId" => 4821,
]);

In practice:

  • use debug for development detail
  • use info for normal application events
  • use notice for unusual but expected situations
  • use warning when something degraded but the request can continue
  • use error when part of the request failed
  • use higher levels such as critical, alert, or emergency only for severe operational failures

By default, WebEngine logs to standard output and sends higher-severity messages to standard error. That default fits container and process-manager environments well, because log collection is usually already wired to those streams.

For application failures, 5xx exceptions are logged automatically. Client-side failures are treated more quietly: 404s are only logged when logger.log_404_to_error_log is enabled, and other handled client errors are not treated as server errors.

For the full list of logger defaults, see Configuration reference#Config section: logger.


The final reference page is project structure reference.

Clone this wiki locally