Jump to content

Non db dependent 'offline' page - for when pw cant reach the db


robinc
 Share

Recommended Posts

With any website, there is the possibility of db issues - overloaded server, network connectivity if the db is on another machine in the hosting network, etc.

I would love to see a feature where if there is any reason the db fails or cannot be accessed, then pw displays a dedicated page that is stored in the filesystem - instead of displaying nothing, or an ugly mysql error. Obviously it would be good to log the error, and possibly send a notification to the admin (email?).

This gives us the opportunity to still present a professional front (albeit with no functionality) while problems are resolved behind the scenes. I cannot think of a company I have worked for that hasn't had db errors at times

What are your thoughts?

  • Like 2
Link to comment
Share on other sites

34 minutes ago, robinc said:

Obviously it would be good to log the error, and possibly send a notification to the admin (email?).

Database errors are always logged. You will find entry in your /site/assets/logs/errors.txt file

2017-03-18 16:05:27    ?    http://example.org/?/    Error:     Exception: SQLSTATE[HY000] [1049] Unknown database 'example' (in .../wire/core/ProcessWire.php line 375)

Depending on your config.php settings an Email will be sent

/**
 * Admin email address
 *
 * Optional email address to send fatal error notifications to.
 *
 * #input email
 * @var string
 *
 */
$config->adminEmail = '';

In case of fatal errors the following html file will be send

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
    <title>500 Internal Server Error</title>
</head>
<body>
    <h1>Internal Server Error</h1>
    <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p>
    <p>{message}</p>
</body>
</html>

You can modify it. You'll find the file (default installation) in /site/templates/errors/500.html

  • Like 10
Link to comment
Share on other sites

  • 2 weeks later...

It would be nice to have an admin interface for managing this file (and linked css). Potentially with wysiwyg editing and preview function, any maybe an 'export from page' option, to create the static file.

 

Link to comment
Share on other sites

And here goes some code. Place this on site/ready.php (or create a module from it) and edit the first lines to your liking:

 

/*************************/
/******* EDIT HERE *******/
/*************************/

// ID of the page where the custom content is
$this->pageID = 1;

// name of the field where the custom content is
$this->fieldName = 'body';

// name of html tag and id from the parent of the custom content on the 505 file
$this->elementTag = 'div';
$this->elementID = 'message';

/*************************/
/******* END EDIT ********/
/*************************/


// regex to get the contents of parent element
$this->regex = '/(<'.$this->elementTag.'\sid=("|\')?'.$this->elementID.'("|\')?>)([^<]|<.+>.*<\/.+>)+(<\/'.$this->elementTag.'>)/i';

// On save the content of the field on the 505.html file
$this->addHookAfter('Pages::saved', function(HookEvent $event) {
  
    $page = $event->arguments[0];

    if($page->id !== $this->pageID) return;

    $file = wire('config')->paths->templates . '/errors/500.html';

    $content = file_get_contents($file);
    $field = $this->fieldName;

    $content = preg_replace($this->regex, '$1'.$page->$field.'$3', $content);

    file_put_contents($file, $content);

});

// On render the edit page, save the content of 505.html file on the field to show it
$this->addHookBefore("ProcessPageEdit::buildFormContent", function(HookEvent $event) {
  
    $page = $event->object->getPage();

    if($page->id !== $this->pageID) return;

    $file = wire('config')->paths->templates . '/errors/500.html';

    $content = file_get_contents($file);

    preg_match($this->regex, $content, $matches);

    if($matches) {

        $page->of(false);
        $field = $this->fieldName;
        $page->$field = $matches[0];
        $page->save($this->fieldName);

    }

});

 

The above code assumes that your "505.html" file has a <div> with the id "message" in it, you just have to adapt it to yours.

  • Like 2
Link to comment
Share on other sites

one thing that is not working for me with the offline files in the template folder:

it seems that if you use delayed output, then there is something in the output buffer already that gets prepended to the html file when rendered;

not sure how to fix this, but it's kind of a problem, can't render a clean 500 error page because of this, due to a bunch of markup being output above the opening <html of the error file...

Link to comment
Share on other sites

  • 2 weeks later...
On 3/28/2017 at 2:48 AM, diogo said:

And here goes some code. Place this on site/ready.php (or create a module from it) and edit the first lines to your liking:

 


/*************************/
/******* EDIT HERE *******/
/*************************/

// ID of the page where the custom content is
$this->pageID = 1;

// name of the field where the custom content is
$this->fieldName = 'body';

// name of html tag and id from the parent of the custom content on the 505 file
$this->elementTag = 'div';
$this->elementID = 'message';

/*************************/
/******* END EDIT ********/
/*************************/


// regex to get the contents of parent element
$this->regex = '/(<'.$this->elementTag.'\sid=("|\')?'.$this->elementID.'("|\')?>)([^<]|<.+>.*<\/.+>)+(<\/'.$this->elementTag.'>)/i';

// On save the content of the field on the 505.html file
$this->addHookAfter('Pages::saved', function(HookEvent $event) {
  
    $page = $event->arguments[0];

    if($page->id !== $this->pageID) return;

    $file = wire('config')->paths->templates . '/errors/500.html';

    $content = file_get_contents($file);
    $field = $this->fieldName;

    $content = preg_replace($this->regex, '$1'.$page->$field.'$3', $content);

    file_put_contents($file, $content);

});

// On render the edit page, save the content of 505.html file on the field to show it
$this->addHookBefore("ProcessPageEdit::buildFormContent", function(HookEvent $event) {
  
    $page = $event->object->getPage();

    if($page->id !== $this->pageID) return;

    $file = wire('config')->paths->templates . '/errors/500.html';

    $content = file_get_contents($file);

    preg_match($this->regex, $content, $matches);

    if($matches) {

        $page->of(false);
        $field = $this->fieldName;
        $page->$field = $matches[0];
        $page->save($this->fieldName);

    }

});

 

The above code assumes that your "505.html" file has a <div> with the id "message" in it, you just have to adapt it to yours.

Thanks @diogo  for this.

___________________________________
Get Assignment help.

Edited by adrian
Removed spammy link
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...