Error Handling
Error Handling
Hazaar Framework provides a robust error handling system that catches exceptions and errors, ensuring they are handled gracefully. By default, it displays a detailed error page in development and a friendly message in production. However, you can fully customise the behaviour to suit your application's needs.
Configuration
Error handling is configured in your application's main configuration file (usually app.php) within the error section.
The two main settings are:
view: Specifies the view script to use when rendering HTML errors.controller: Specifies the controller class responsible for handling errors.
Example app.php configuration:
'error' => [
'view' => 'error',
'controller' => 'App\Controller\Error',
],Customizing the default Error View
The simplest way to customize the look and feel of your error pages is by creating a custom view.
Setting the View
First, define the name of your view in the configuration:
'error' => [
'view' => 'my_custom_error',
],Then, create the view file in your views directory (e.g., app/views/my_custom_error.tpl).
Note
If you would like more fine-grained control over your error views you can define views based on the response code. See: Automatic HTTP Error Views
Available Variables
The Hazaar\Controller\Error controller passes several variables to the view, which you can use to display relevant information:
$err: An array containing details about the error:message: The error message string.code: The error number or exception code.file: The file path where the error occurred.line: The line number where the error occurred.class: The class name of the exception (if applicable).type: The error type.
$status: The HTTP status message (e.g., "Not Found", "Internal Server Error").$code: The HTTP status code (e.g., 404, 500).$trace: The stack trace of the error.$env: The current application environment (e.g., 'development', 'production').
Example View
Here is a simple example of what an error view might look like using the Smarty template engine:
<!DOCTYPE html>
<html>
<head>
<title>Error {$code}</title>
</head>
<body>
<h1>{$status}</h1>
<p>We encountered an issue: {$err.message}</p>
{if $env == 'development'}
<hr>
<h3>Debug Info:</h3>
<p>File: {$err.file}:{$err.line}</p>
<pre>{print_r($trace, true)}</pre>
{/if}
</body>
</html>Automatic HTTP Error Views
You can also create custom error views for specific HTTP error codes by creating a directory named error in your views directory (e.g. app/views/error). Inside this directory, simply create view files named with the HTTP status code you wish to handle.
For example, to handle 404 errors, create app/views/error/404.tpl. For 500 errors, create app/views/error/500.tpl.
Hazaar will automatically detect these files and use them when the corresponding error occurs, without any additional configuration.
Overriding the Error Controller
For scenarios requiring logic beyond simple display changes—such as logging errors to an external service, sending notifications, or handling specific content types uniquely—you can override the default error controller.
The built-in error controller is Hazaar\Controller\Error.
Creating a Custom Controller
To create a custom error handler, define a new controller class that extends Hazaar\Controller\Error. This allows you to inherit the existing functionality while overriding specific methods, such as html(), json(), xml(), or text(), depending on the response type you want to customize.
Example: application/controllers/Error.php
namespace App\Controller;
use Hazaar\Controller\Response\HTML;
class Error extends \Hazaar\Controller\Error {
public function html(): HTML {
// Perform custom actions, such as logging to a specific system
// Log::write("Error: " . $this->errstr);
// You can return a custom response directly
// return new HTML('<h1>Critical Error</h1>');
// Or call the parent method to render the configured view
return parent::html();
}
}Handling Different Content Types
The Hazaar\Controller\Error controller is designed to automatically respond with the appropriate content type based on the request headers (specifically the Accept header).
html(): Called when the request expects HTML (e.g., a standard browser request). This is the default method.json(): Called when the request expects a JSON response (e.g., AJAX requests expectingapplication/json). This method returns aHazaar\Controller\Response\JSONobject containing a structured error object.xml(): Called when the request expects XML (e.g.,application/xmlortext/xml). This method returns aHazaar\Controller\Response\XMLobject with a SOAP-like fault structure.text(): Called for plain text requests. This enables a text-based stack trace and error info.
When overriding Hazaar\Controller\Error, you can choose to override one or all of these methods to customize the output for specific clients (like an API consumer vs. a web browser).
For example, to customize the JSON error response for your API:
public function json(): \Hazaar\Controller\Response\JSON {
$response = [
'success' => false,
'error' => $this->message,
'code' => $this->code
];
return new \Hazaar\Controller\Response\JSON($response, $this->code);
}Registering the Custom Controller
After creating your class, update the app.php configuration to tell Hazaar to use your new controller:
'error' => [
'controller' => \App\Controller\Error::class,
// ... other settings
],Now, whenever an error occurs, Hazaar will instantiate App\Controller\Error instead of the default handler, complying with your custom logic.
Custom Exceptions in JSON Responses
When creating APIs, you often need to return specific JSON structures for different types of errors. Hazaar makes this easy by allowing you to define custom exception classes that determine their own JSON representation.
Creating a Custom Exception
The Hazaar\Exception class implements the JsonSerializable interface. By extending Hazaar\Exception and overriding the jsonSerialize method, you can control the JSON output.
Example:
namespace App\Controller\Exception;
use Hazaar\Exception;
class Wobble extends Exception
{
public function jsonSerialize(): array
{
return [
'wobble' => true,
'message' => $this->getMessage()
];
}
}Usage
When you throw this exception from a controller action that returns a JSON response, Hazaar will automatically use the array returned by jsonSerialize as the response body.
namespace App\Controller;
use App\Controller\Exception\Wobble;
use Hazaar\Controller\Action;
use Hazaar\Controller\Response\JSON;
class MyController extends Action
{
public function test(): JSON
{
// Ensure the response type is set to JSON if not done automatically
// based on the request headers or return type.
throw new Wobble('Something went wrong!', 501);
}
}This will produce a JSON response with a 501 status code:
{
"wobble": true,
"message": "Something went wrong!"
}