catching a php error

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

catching a php error

Post by IGGt »

Hi guys,

I have a script which runs queries against some MySQL databases, and then displays the results in a table. I have built into it a section for catching MySQL errors, and displaying the error as the result, but today, one of my servers went offline, and the whole script failed, displaying just:

Code: Select all

Warning: mysql_connect() [function.mysql-connect]: [2002] A connection attempt failed because the connected party did not (trying to connect via tcp://1.2.3.4:3306) in mysql.php on line 245

Warning: mysql_connect() [function.mysql-connect]: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. in mysql.php on line 245

Fatal error: Maximum execution time of 60 seconds exceeded in mysql.php on line 245
I'm wondering, is there a way of catching this PHP error, so that I can display a message, and then allow the rest of the script to carry on afterwards, like I do with the MySQL errors?
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: catching a php error

Post by requinix »

You can "catch" many kinds of errors in PHP, but most fatal errors are not on that list. If you don't want errors displayed that's a different matter.

Make sure the connection timeout for MySQL is fairly low (much lower than the execution_limit in PHP), and if the connect fails then check mysql_error() for what happened.
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

cheers,
I changed the mysql.connect_timeout to 30, in my php.ini file but it hasn't made a difference, I still get the same error messages, is there any other settings I need to change?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: catching a php error

Post by Weirdan »

tasairis wrote:You can "catch" many kinds of errors in PHP, but most fatal errors are not on that list.
In fact you can handle fatal errors (including parse errors) via register_shutdown_function() + error_get_last():

Code: Select all

// q.php
<?php
    function handler()
    {
        var_dump(error_get_last());
    }

    register_shutdown_function('handler');
    error_reporting(0);

    include('q2.php');

Code: Select all

// q2.php
<?php
    rekr3
    'adsfwe
    vnv
    "\\\\\'............>'"
outputs:

Code: Select all

weirdan@home:~$ php q.php
array(4) {
  ["type"]=>
  int(4)
  ["message"]=>
  string(51) "syntax error, unexpected T_CONSTANT_ENCAPSED_STRING"
  ["file"]=>
  string(22) "/home/weirdan/q2.php"
  ["line"]=>
  int(5)
}
weirdan@home:~$
Of course you can't continue execution (and there are other limitations with this technique), but you can handle fatal errors.
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

Hi Weirdan,

thanks for your response (I've been busy on other projects, and only now getting back to this one).

I'm looking at your code, and have added it to my script as follows:

function handler() etc. is placed at the top (after the info relating to sessions).

I've copied q2.php to a separate file (called q2.php) in the same folder as my script. But whenever this runs I get:

array(4) { ["type"]=> int(4) ["message"]=> string(11) "parse error" ["file"]=> string(31) "C:\wamp\www\Local\slaves\q2.php" ["line"]=> int(6) }

at the top of the screen and nothing else.

e.g. I have

Code: Select all

<?php

session_name('slaveLocal');

session_start();  
if(isset($_SESSION['views']))
    $_SESSION['views'] = $_SESSION['views']+ 1;
else
    $_SESSION['views'] = 1;

    
    
function handler()
    {
        var_dump(error_get_last());
    }

    register_shutdown_function('handler');
    error_reporting(0);

    include('q2.php');    
    
the rest of my script goes here. . . 

I'm guessing this is wrong. My Guess is I am looking for something like:

If error occurs
call handler() > display q2.php

is this right, in which case can you tell me how I would catch the error?
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

OK, I've put together the following code from information I have found:

Code: Select all

set_error_handler('myErrorHandler');
register_shutdown_function('fatalErrorShutdownHandler');

function myErrorHandler($code, $message, $file, $line) {
	//error message
    $errorMsg = $this->getMessage();
    return $errorMsg;
    }

function fatalErrorShutdownHandler()
{
  $last_error = error_get_last();
  if ($last_error['type'] === E_ERROR) {
    // fatal error
    myErrorHandler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
    return $last_error['message'];
  }
}
   
error_reporting(0);
I then cause one of the mysql_connect() to fail by changing the connection parameters (the same effect as someone turning off the server). And this almost works, in that it doesn't give a nasty looking error message, and also doesn't try to execute the PHP below it, but it doesn't give me any kind of error message. I was expecting that either:
return $errorMsg;
return $last_error['message'];
would show up on the screen as a nicely formatted message, instead I just get a blank screen (and any html elements not created in PHP). I feel like I am close. If anyone can see the mistake(s) I would appreciate it.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: catching a php error

Post by Weirdan »

IGGt wrote:I'm guessing this is wrong.
No, this is right. You cannot continue execution after fatal error, however you can handle the error itself and, for example, redirect user to feedback page asking them for fill a bug report, or create a ticket in your bugtracker automatically, or send an email to yourself. You just can't pretend the error never happened.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: catching a php error

Post by Weirdan »

IGGt wrote:And this almost works, in that it doesn't give a nasty looking error message, and also doesn't try to execute the PHP below it, but it doesn't give me any kind of error message. I was expecting that either:
return $errorMsg;
return $last_error['message'];
would show up on the screen as a nicely formatted message
return in shutdown handler won't do anything useful. If you need nicely formatted message shown to user you have to format it nicely and send it to user yourself. Something like this:
// error.phtml

Code: Select all

<html>
 <title>Error</title>
<head>
</head>
<body>
<h1>Error</h1>
<p>We're very sorry, but it seems you've hit the bug. Please contact admin@site.com and send them the following:</p>
<pre>
[<?php echo $error['type'];?>] <?php echo $error['message']?> in <?php echo $error['file']?>:<?php echo $error['line']?>
</pre>
</body>
</html>
// script.php

Code: Select all

<?php
register_shutdown_function('fatalErrorShutdownHandler');
function fatalErrorShutdownHandler()
{
  $error = error_get_last();
  if ($error['type'] === E_ERROR) {
    // fatal error
    while (ob_get_level()) ob_end_clean(); // clean up output buffers
    if (!headers_sent()) {
         header('HTTP/1.1 500 Internal Server Error'); // be nice to computers, follow http standards
    }
    include('error.phtml'); // be nice to humans, show friendly error message
  }
}

// now, run everything else prepared to handle errors gracefully
include('q2.php');
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

cheers,

I now have:

Code: Select all

<?php

session_name('slaveLocal');

session_start();  
if(isset($_SESSION['views']))
    $_SESSION['views'] = $_SESSION['views']+ 1;
else
    $_SESSION['views'] = 1;
   
register_shutdown_function('fatalErrorShutdownHandler');
function fatalErrorShutdownHandler()
{
  $error = error_get_last();
  if ($error['type'] === E_ERROR) {
    // fatal error
    while (ob_get_level()) ob_end_clean(); // clean up output buffers
    if (!headers_sent()) {
         header('HTTP/1.1 500 Internal Server Error'); // be nice to computers, follow http standards
    }
    include('error.phtml'); // be nice to humans, show friendly error message
  }
}    
    
// now, run everything else prepared to handle errors gracefully
include('q2.php');

... rest of the script ...
error.phtml is copied from what you posted for the moment.
q2.php simply prints the word hello in order to stop it giving an error of it's own.

But when I run this I get:
[text]
Warning: mysql_connect() [function.mysql-connect]: [2002] A connection attempt failed because the connected party did not (trying to connect via tcp://localhost:3305) in C:\wamp\www\Local\slaves\CheckSlavesv8.php on line 202

Warning: mysql_connect() [function.mysql-connect]: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. in C:\wamp\www\Local\slaves\CheckSlavesv8.php on line 202

Warning: mysql_query() expects parameter 2 to be resource, boolean given in C:\wamp\www\Local\slaves\CheckSlavesv8.php on line 203

Warning: mysql_fetch_assoc() expects parameter 1 to be resource, null given in C:\wamp\www\Local\slaves\CheckSlavesv8.php on line 205
[/text]

But I thought that the newly added script would catch this and display error.phtml instead.
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

I'm almost there I think.

I put

Code: Select all


<html>
 <title>Error</title>
<head>
</head>
<body>
<h1>Error</h1>
<p>We're very sorry, but it seems you've hit the bug. Please contact admin@site.com and send them the following:</p>
</body>
</html>
into q2.php, and now it gives me
[text]
Error

We're very sorry, but it seems you've hit the bug. Please contact admin@site.com and send them the following:
[/text]

repeated four times, as well as anything that was generated in html directly for that page. If I can get to the point where it only shows one error messageinstead of four I'll be very happy.
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

ah...

the simple addition of

Code: Select all

<?php
die();
?>
to the q2.php file seems to have done the trick.
zainmirza
Forum Newbie
Posts: 3
Joined: Wed Oct 27, 2010 8:11 am

Re: catching a php error

Post by zainmirza »

IGGt wrote:Hi guys,

I have a script which runs queries against some MySQL databases, and then displays the results in a table. I have built into it a section for catching MySQL errors, and displaying the error as the result, but today, one of my servers went offline, and the whole script failed, displaying just:

Code: Select all

Warning: mysql_connect() [function.mysql-connect]: [2002] A connection attempt failed because the connected party did not (trying to connect via tcp://1.2.3.4:3306) in mysql.php on line 245

Warning: mysql_connect() [function.mysql-connect]: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. in mysql.php on line 245

Fatal error: Maximum execution time of 60 seconds exceeded in mysql.php on line 245
I'm wondering, is there a way of catching this PHP error, so that I can display a message, and then allow the rest of the script to carry on afterwards, like I do with the MySQL errors?
By Zain Ali
Note:- if you find any error relative to MySql Database so there is a built-in function which tell to user which is mistake, the
function is mysql_error() . THis function can be used in Php tags. the technical description of the this function is that, this function relative to MySql Data Base Management System.
IGGt
Forum Contributor
Posts: 173
Joined: Thu Nov 26, 2009 9:22 am

Re: catching a php error

Post by IGGt »

Cheers,

I think I have it all sussed now. Any errors within MySQL (e.g. incorrect syntax) are caught and handled, and displayed as such within the normal script.
Any PHP errors (e.g. server can't be contacted) are now handled by re-directing to another page (which in turn sends an email to inform me).
Post Reply