Error Pages - Jet\ErrorPages

The purpose of Jet ErrorPages is to encapsulate and unify the logic for handling error pages.

First of all, what is an error page. It is, for example, a "forty-four". That is, if a user gets to a URL that no longer exists, for example, you need to both return a correct HTTP 404 code, but also show the user some sort of informational page. Or your site is temporarily down for maintenance and you need to give the user a 503 code and again some info page. Something needs to take care of those pages. Something has to display them somehow. We'll come back to that later.

Then there's the app. It detects (perhaps by Jet MVC) that the request URL is no longer valid. Or that the base is currently deactivated. Or that access to that part of the site is not allowed. And so on. The application simply evaluates this state and wants to serve it.

Of course, the place in the application that evaluated the state has no idea how such a "fourteen" should look like. And in fact, the controller of some application module (for example) has nothing to do with it, it is not its place to deal with something like that. Moreover, the solution of the same would be in countless places - which is unacceptable. That's why, for example, the controller only needs to say: I have a "forty-four" - take care of it. That's all the controller (or any other place in the application) cares about.

And that's what Jet ErrorPages is for. Let's just show how the controller asks for a "forty-four" for example: ErrorPages::handleNotFound();

And that's all... That's all it solves.

Or what if a part of your project is temporarily unavailable?

ErrorPages::handleServiceUnavailable();

But there is no need to limit yourself. Any HTTP code can be served:

ErrorPages::handleHttp_Headers::CODE_402_PAYMENT_REQUIRED );

We have shown examples of this in use. Of course, next we'll show how to define the other end - that is, how to secure the operator. But at the same time, I wanted to show what the goal and purpose of ErrorPages is. That is, to provide a transparent and unified interface for handling all sorts of (error) conditions.

Initializing error pages

And now we'll show how to provide error page handling. Jet offers several options that can be combined, and we will show them in turn.

View error pages in a specific directory

This is the default method of how ErrorPages builds and displays an error page. It works by trying to find a file whose name matches the HTTP code and has a .phtml extension in the directory that is specified by the SysConf_Jet_ErrorPages::getErrorPagesDir() setting. This is actually a simplified view script and can therefore be scripted in - it doesn't have to be a strictly static page.

Before we show an example, let's stop at setting the directory path, which is done with the SysConf_Jet_ErrorPages::setErrorPagesDir('somer/dir') method. If the directory is not set up, this method of displaying error pages does not work. If you want to use it, you must set it up. And on that note, let's take a detour to Jet MVC. If you're already familiar with Jet MVC, you know what a base initializer is. And the base initializers are where you should set up your error page directory. Let's show an example from a sample application:

namespace JetApplication;

use 
Jet\MVC_Router;
use 
Jet\SysConf_Jet_ErrorPages;
//... ... ..

class Application_Web
{
    
//... ... ...

    /**
     * @param MVC_Router $router
     */
    
public static function initMVC_Router $router ): void
    
{
        
//... ... ...
        
SysConf_Jet_ErrorPages::setErrorPagesDir
            
$router->getBase()->getPagesDataPath$router->getLocale() ) 
        );
    }

}

As you can see, the sample application sets the error page directory to the root pages of the current location of the current base. In practice, this means that, for example, in the ~/application/bases/web/pages/cs_CZ/ directory you'll find files 401.phtml, 404.phtml and 500.phtml - and these are already view for error pages. This allows each mutation of each base to have its own error pages.

The use of this method is, of course, only a recommended (albeit highly recommended) practice. Technically, you are not restricted in any way and can direct the directory where you need it or use another method.

Displayer

It may happen that you are not comfortable with view and want to implement your own view logic. With that said, everything will remain the same (the interface for the application and sending HTTP headers), only your logic will take care of generating the HTML error page. If such a situation arises, you can define so-called viewers for individual HTTP codes. Let's see it in practice:

ErrorPages::setDisplayer(404, function() {
    echo 
'This is my 404';
});

Own handler

What if you want to do something very special for a certain code? Maybe even keep the display system, but log something before displaying the error page, for example? This is also possible. Just make your own handler:

ErrorPages::setHandler(404, function() {
    
IO_File::append('my/404.log''404 log record');
});

How error pages are handled

Let's see in detail what actually happens when anything from the application calls for example:

ErrorPages::handleNotFound();

The process is as follows:

  • Checks if a handler exists for the given HTTP code (here 404). If so, it is called and the subsequent process continues.
  • Using Http_Headers::response( $code ); HTTP headers are sent.
  • See if a displayer is defined for the HTTP code. If so, it is called and the display of the error page is fully left to it.
  • If the displayer is not defined, then it is checked whether the directory that should contain the error pages is set.
  • If the directory is set, then it is searched for a file whose name matches the HTTP code and whose extension is .phtml.
  • If such a file/script exists, it is executed and the error page is displayed.
  • The application is terminated (unless the optional parameter $application_end is false).

Overview of Jet\ErrorPages class methods

Method Meaning of
public static handle(
int $code,
bool $application_end = true
): void
Serves any HTTP code / state.

The application_end parameter specifies whether the application should be terminated immediately after serving.
public static handleServiceUnavailable(
bool $application_end = true
): void
Serves HTTP code / state 503.

The application_end parameter specifies whether the application should be terminated immediately after serving.
public static handleInternalServerError(
bool $application_end = true
): void
Serves HTTP code / state 500.

The application_end parameter specifies whether the application should be terminated immediately after serving.
public static handleUnauthorized(
bool $application_end = true
): void
Serves HTTP code / 401 state.

The application_end parameter specifies whether the application should be terminated immediately after serving.
public static handleNotFound(
bool $application_end = true
): void
Serves HTTP code / 404 status.

The application_end parameter specifies whether the application should be terminated immediately after serving.
public static display(
int $code
): bool
It only displays an error page for the code (does not send HTTP headers, does not call the handler, does not terminate the application).
public static getErrorPageFilePath(
int $code
): bool|string
Returns the full path to the view script error page for the given code. But only if the directory path is set and the script exists. Otherwise, it returns false.
public static setHandler(
int $code,
callable $callback
): void
Sets the handler for the given code/state.
public static unsetHandler(
int $code
): void
Cancels the handler for the given code/state.
public static setDisplayer(
int $code,
callable $callback
): void
Sets the display for the given code/status.
public static unsetDisplayer(
int $code ): void
Clears the display for the given code/status.
Previous chapter
Jet\Db_Backend_PDO_Config
Next chapter
Session - Jet\Session