Custom Error Message in Script Crash? PHP - php

I've never worked with advanced error handling, and I can't find an obvious answer searching.
In the scope a script (require_once) how do you set up a custom "die" message?
Generally my users see the page-load die with no response. I'd like to direct them to a help file regarding memory so they absolutely cannot miss the solution.

You can kill a script and output a message using the die() command
die("Your message here");
You can also throw custom exceptions in PHP 5+, and catch them and at that point output a message to the users.
http://php.net/manual/en/language.exceptions.php

require_once automatically stops execution if it fails.
Try e.g. (include_once file.php) or header('Location: http://.../path/to/help');, or
if(!(include_once file.php)) {
// redirect?
}

Related

php session_start general error handling

I'm looking for a general way to handle session_start errors, not a way to handle one specific error. There are numerous errors which can happen, such as the session directory being full, which cause a fatal error. I want a way to trap those errors and handle them cleanly, without having to write custom handlers for each possibility.
Something like this (but not this as it doesn't work):
try{
session_start();
}catch(Exception $e){
echo $e->getMessage();
}
All help appreciated, thanks in advance.
The regular PHP session functions don't throw exceptions but trigger errors. Try writing an error handler function and setting the error handler before calling session_start.
function session_error_handling_function($code, $msg, $file, $line) {
// your handling code here
}
set_error_handler('session_error_handling_function');
session_start();
restore_error_handler();
However, this is just for capturing the session errors. A better way would be to create a general error handler that creates exceptions from errors and surround code parts that may throw errors with try ... catch blocks.

How to propery finish a PHP page after an exception is thrown and caught?

I am working on my first major PHP/MySQL application. I use the Exception handling mechanism to handle possible DB errors. On some pages, I use several queries to obtain the relevant data from the database. The part of the page issuesn those queries is within one try-catch block and I write a customized error message in the catch block.
My problem: the queries are within different blocks on my page, and when a DB exception is thrown, processing immediately goes to the catch block and makes it not really possible to render the page in valid XHTML because in the catch block it is not known which XHTML tags should be closed.
I was thinking about redirecting to a custom error page showing the error mesage but this appears to be discouraged by some people. I think this should be a pretty trivial issue but wonder what is the recommended practice.
Hope for some hints!
1) Change the default error handler. Log them in a database
2) use output buffering
3) last line of your Catch{} block, have it do a header("location: error.html") redirect to a generic error handler.
You should use ob_start() to start buffering the output, and then you have finished to render all the HTML, use ob_flush() to send the HTML code back to the user.
If an error occured, you can generate a special page by calling ob_clean() to clean the buffer and then display your error page.
Exemple :
ob_start();
echo "My title";
try{
$myDB = Database::getInstance();
$userName = $myDB->query("SELECT name FROM user"); // send an exception
echo "Welcome ".$userName;
} catch (Exception $e) {
ob_clean();
echo "Error, please try again";
}
ob_flush();
I'm shure that DB query error is mostly debug enviroment issue or code error. I also prefer to validate and escape values in DB query before running it and show validation result, when it failed.
So, if DB exception even appeared, i log it (using simple error_log, including full request data, get, post, url, referrer) and show 500 error page without any redirect. I think, that redirect is a bad practice - you can't refresh page and repeat error, visitors and QA can't send you invalid page link.
I used the ob_Start(), ob_flush() and ob_clean() method and it does what I excepted so I keep using this.
I will wonder whether this is considered as good practice, IMHO generating invalid XHTML should always be avoided.
Of course an error in the query is a bug and one can argue whether this should be handled in the production code. But my guess is that in the future a lot of maintenance will be done and errors will be inevitable. And they should be presented as nice as possible and surely not in the form of a white blank screen...

Errors when calling exit() function for fastCGI?

I've been reading that people face problems when using the exit function in their php script while running fastCGI
https://serverfault.com/questions/84962/php-via-fastcgi-terminated-by-calling-exit
http://php.net/manual/en/function.exit.php
"It should be noted that if building a site that runs on FastCGI, calling exit will generate an error in the server's log file. This can quickly fill up."
However my error log isn't reporting this problem after running this simple script even though I have fastCGI configured:
<?php
$num=2;
if($num==2){
exit();
}
?>
Would it be safe to use the exit function while I have fastCGI configured? And are there any alternatives to the exit function in php?
EDIT: I'm using the exit() function form form validation (ie if a form is valid exit, if not parse all the posted variables into the text fields.)
There are a few legitimate reasons to use exit() which is the same as die(). One example would be to follow a header Location: redirect.
Form validation is not the place to use die(). Structure your code so that you utilize functions or classes with methods that return values instead, and utilize branching logic.
In terms of fastcgi, if exit is used appropriately for situations where code is reached that should not be, then those situations will be atypical and a few log messages should not be a problem. Having a log file fill up seems a pretty silly reason not to do something -- an active webserver is logging every request and nobody argues that you shouldn't have a web log.
There's a really nice alternative to exit() posted on the exit() man page by
"dexen dot devries at gmail dot com":
If you want to avoid calling exit() in FastCGI as per the comments
below, but really, positively want to exit cleanly from nested
function call or include, consider doing it the Python way:
define an exception named `SystemExit', throw it instead of calling
exit() and catch it in index.php with an empty handler to finish
script execution cleanly.
<?php
// file: index.php
class SystemExit extends Exception {}
try {
/* code code */
}
catch (SystemExit $e) { /* do nothing */ }
// end of file: index.php
// some deeply nested function or .php file
if (SOME_EXIT_CONDITION)
throw new SystemExit(); // instead of exit()
?>

PHP how to trigger user error with trigger_error in an object destructor while the script shuts down?

While implementing some class I've run into a little problem:
If the script ends and destructors are called because the script has finished, I wanted to trigger an error occasionally.
I thought the trigger_error() function would be of use. However, if error_reporting(-1) the triggered error is not send any longer to STDOUT or STDERR - while it is expected to do so (e.g. if not within the __destructor/termination phase of the script, trigger_error works as expected).
If I echo some message out, it will be send to STDOUT (CLI mode).
I now wonder
how I can trigger an error in this phase of the application?
and/or alternatively how can I detect that currently the script is shutting down because it has successfully ended?
Note: I tested connection_status() but it's useless in my case as it's about connection handling only and merely unrelated. I wonder if there is some function that does the same for the scripts execution status (starting, running, exiting).
Simplified Example Code
This is some very reduced example code to illustrate the issue. Naturally is the error only triggered if it makes sense for the object:
<?php
class TriggerTest
{
public function __destruct()
{
trigger_error('You should have missed something.');
}
}
$obj = new TriggerTest;
exit();
The problem is, that trigger_error() gets executed but the error does not appear anywhere.
How about if you force the error reporting to be a certain setting, trigger the error and then set the error reporting back to it's normal form?
Answer: Just do it. I had some misconfiguration for the error handler and therefore it did not work. My fault.
However it's still interesting if there is any function or similar to determine the execution state on shutdown.

PHP custom error page

Everyone says that "Enabling errors to be shown" in an active site is bad (due to some security issues).
Now, we have to consider 2 cases:
The site is in debug mode
The site is not in debug mode
Now, for case #1:
We want to see the errors. How?
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);
Nothing more simple. Also we can customize an error handler for all errors except Parse and Fatal.
Instead, if the case is #2:
We would like to be able to deactivate the messages:
ini_set('error_reporting', 0);
ini_set('display_errors', 0);
And it's ok. But what about showing users a friendly message such as "Hei man, something is really f**ked up. I don't assure you we are working to fix it, since we are very lazy.".
You should enable errors again and just use the function set_error_handler() and hope that no parse or fatal errors occur. But my first question is:
Question 1: Is that possible to avoid error reporting and have a custom offline page that is loaded when something goes wrong? I mean, is it possible to have ini_set('error_reporting', 0); and ini_set('display_errors', 0); and still be able to tell PHP to load a custom Error page?
And now another:
Question 2: I developed a class that with the power of set_error_handler() logs errors occurred into the database. In this way I can keep track of hack attempts and other cool stuff. (And yes, i'm always sure the DB is accessible since my application shuts down if we cannot connect to the DB). Is this worth something?
Some time ago I created small system that redirects you to error page when fatal error occurs / uncaught exception was thrown. It was possible with assumption, that every request is handled by one file and ends in this file, so by reaching end of this file I'm sure that everything went OK. With this condition I've set up function to redirect on error page and registered it as shutdown function - so it will be called at the end of all requests. Now in this function I check conditions for clean shutdown and if hey are met, I do nothing and output is flushed to the browser, otherwise buffer is cleaned and only header redirecting to error page is sent.
Simplified version of this code:
<?php
function redirect_on_error(){
if(!defined('EVERYTHING_WENT_OK')){
ob_end_clean();
header('Location: error.html');
}
}
register_shutdown_function('redirect_on_error');
ob_start();
include 'some/working/code.php';
echo "Now I'm going to call undefined function or throw something bad";
undefined_function();
throw new Exception('In case undefined function is defined.');
define('EVERYTHING_WENT_OK', TRUE);
exit;
Question 1: Is that possible to avoid error reporting and have a custom offline page that is loaded when something goes wrong?
Unfortunately, I don't think so, at least for fatal errors. However, recent versions of PHP always send a 500 response when that occurs, so, depending on webserver, you may be able to rewrite the response if such thing happens. If your actual server running PHP is behind a reverse proxy, this becomes trivial with Apache.
Question 2: I developed a class that with the power of set_error_handler() logs errors occurred into the database.
Sure, it's always good to log the errors. You already seem to be aware of the limitations of logging errors into the database.

Categories