Page 1 of 1
catching a php error
Posted: Tue Sep 28, 2010 7:22 am
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?
Re: catching a php error
Posted: Tue Sep 28, 2010 8:06 am
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.
Re: catching a php error
Posted: Tue Sep 28, 2010 11:31 am
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?
Re: catching a php error
Posted: Tue Sep 28, 2010 1:33 pm
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.
Re: catching a php error
Posted: Tue Oct 26, 2010 9:37 am
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?
Re: catching a php error
Posted: Tue Oct 26, 2010 11:25 am
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.
Re: catching a php error
Posted: Tue Oct 26, 2010 11:42 am
by Weirdan
IGGt wrote:I'm guessing this is wrong.
No, this is right. You can
not 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.
Re: catching a php error
Posted: Tue Oct 26, 2010 12:00 pm
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');
Re: catching a php error
Posted: Wed Oct 27, 2010 5:55 am
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.
Re: catching a php error
Posted: Wed Oct 27, 2010 6:30 am
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.
Re: catching a php error
Posted: Wed Oct 27, 2010 8:01 am
by IGGt
ah...
the simple addition of
to the q2.php file seems to have done the trick.
Re: catching a php error
Posted: Wed Oct 27, 2010 8:21 am
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.
Re: catching a php error
Posted: Wed Oct 27, 2010 11:20 am
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).