I am running a php script in command line that connects to a oracle and mssql to fetch some data and write to a file. Actually it was a cron on linux machine which needed to be transfered to windows 2008.
The command is throwing the error:
fatal error call to undefined method MDB2_error::disconnect() in
path\to\script.php in line63
The code around line 63 are:
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
$db_clw->disconnect();
$db_banner->disconnect();
die($db->getMessage());
}
any idea?
You are calling the disconnect method on a MDB2 error object. That method does not have a disconnect method.
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
$db_clw->disconnect();
// ^ method does not exist
$db_banner->disconnect();
die($db->getMessage());
}
Since you call die immediately, there is probably no need to use disconnect at all, but if $db_clw is MDB2_Error, it has no method disconnect, so you should not attempt to call it. The attempt to call it will only occur if there is an error.
When it throws an error here
$db_clw->disconnect();
You already know that $db_clw is not a MDB2 Driver, but rather an error. As such, it doesn't have a disconnect method, so that line should be deleted.
You might want to surround your other disconnect statement there with a try-catch, such as:
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
//We now know $db_clw is an error, don't attempt to disconnect.
try {
$db_banner->disconnect();
} catch (Exception e) {} //ignore it.
//die($db->getMessage()); Not sure if this is what you want, I'd think
die($db_clw->getMessage())
}
ignoring any problems with disconnecting, so that the statement die($db->getMessage()); is reached, which will help you determine why $db_clw = MDB2::factory($config->database->CLW->dsn); is failing.
Just noticed, and updated the code above to change the last statement to die($db_clw->getMessage());, which seems, probably, to be what your looking for there.
Related
after move all rowCount() Functions return fatal error
Fatal error: Call to a member function rowCount() on a non-object
i use this function like this :
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
This means something went wrong while executing the query. Perhaps something went wrong with the update and MySQL isn't running anymore? Verify this, make sure MySQL is running.
Also, you can try to run the same query in PhpMyAdmin to see if that works. If it does, you're sure this is a problem with PDO. If it doesn't, something must be wrong with the MySQL server.
But perhaps the easiest way to debug is to do something like this:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
With this, PDO will throw an exception when the query fails. Then put the query in a try ... catch block:
try {
$co = $pdo->query("SELECT * FROM `tbl_users`");
$pages->items_total = $co->rowCount();
} catch (PDOException $e) {
echo $e->getMessage();
}
This will give you more debug info. When the query fails, the exception will be caught by the catch block, and the message will be outputted. This message usually tells you where the problem is.
This is a general question regarding exception handing for exceptions thrown in onther people's code.
I am using the following Codeigniter PHP library: https://github.com/sepehr/ci-mongodb-base-model
which relies upon this library for MongoDB: https://github.com/alexbilbie/codeigniter-mongodb-library/tree/v2
If I call a function in the first library, and it then calls one from the second. Sometimes the second library throws exceptions which I want to be able to deal with in my own code, but there is a try-catch statement around the exception throwing call, which means that it is dealt with before I get a chance to (I just prints the exception to the screen).
My question is:
Without modifying all of the functions in the first and second libraries (i.e. removing all of the try catches), how can I deal with the exception that is thrown?
EDIT
This is how the functions in the second library are arranged:
class SomeClass
{
function do_something()
{
...
try {
...
}
catch {
$this->_show_error('Update of data into MongoDB failed: ' . $exception->getMessage(), 500);
}
}
function _show_error($error_message = '', $response_code = 500)
{
//Inbuilt Codeigniter helper function which can be disabled from printing the error to the screen
show_error($error_message, $response_code);
}
}
Although I can disable the error from being printed (which is of course just for debugging), I still have no way of knowing that it occurred and handling it.
(should be a comment rather than an answer, but it's a bit long)
just prints the exception to the screen
Really? Are you sure?
Did you check it doesn't trigger an error instead of an exception and you're running this on a system which is not configured as a production server?
If so then I'd steer way clear of this as a library.
(I sincerely doubt anyone would write code that dumb and publish it without lots of warnings)
I'm writing an application, where I thought all the errors were being handled, including fatal ones.
But now I found one error that results in a white screen, and the error only shows up in the webserver log.
$nonExistentVar + 1; // Notice error, gets caught and pretty error is displayed
$existentVar->nonExistentMethod(); // Fatal error, gets caught and pretty error is displayed
$nonExistentVar->nonExistentMethod(); // White screen, error can be seen in nginx.error.log
Is the last error uncatchable? Or what could the problem be?
I'm using Silex, not sure if that matters.
The way I understand it, exceptions can be caught but fatal errors cannot. I am curious to know how you are 'catching' the fatal error in example #2?
Why not use a php is_a() test to see if $nonExistentVar is of the correct class before attempting to call the method? Or possibly in conjunction with method_exists() if you still don't know if a class has a given method available.
Try putting only the last line:
$nonExistentVar->nonExistentMethod();
That works for me, as Symfony\Component\Debug\ExceptionHandler sends the response immediately upon encountering the first Error:
public function handle(\Exception $exception)
{
if (class_exists('Symfony\Component\HttpFoundation\Response')) {
$this->createResponse($exception)->send();
} else {
$this->sendPhpResponse($exception);
}
}
I want to prevent situation when PHP throws an error in case of my bad or failed loading something (eg from remote server). Recently I started to using try-catch block to avoid fatal errors so user don't know that something is screwed up.
Look at my code:
try
{
$flashRAW = file_get_contents($getXml);
$flashXML = simplexml_load_string($flashRAW);
}
catch(Exception $e)
{
return $e->getMessage();
}
$xmlString = $flashXML->asXML();
Using "return" is my invention (I think, I've never seen that...). With return my application will continue to work and I won't have "trying to get property on a non-object" error. Without return I will get it - I think it's stupid because I use try-catch to prevent this...
Is using return this way OK? Is better way to handle exception and make that application will continue work without fatal error? Somewhere I read that try-catch is intended to handle logic errors and increase memory consuming.
I think the issue you are getting is becasue of '$flashRAW' not being defined if there is an exception.
You should check '$flashRAW' before calling '$flashXML->asXML()'.
If you use return no code executes in the function / page depending where you have your code.
Choice to use return or not is more based on Use Case. So depends how you use it.
You need to use libxml_use_internal_errors if you want to catch the exceptions it raises, do that before your try/catch block
libxml_use_internal_errors(true);
I know, that by its very definition, a fatal exception is supposed to kill the execution, and should not be suppressed, but here's the issue.
I'm running a script that scrapes, parses and stores in a DB about 10,000 pages. This takes a couple of hours, and in rare cases (1 in 1000) a page fails parsing and throws a fatal exception.
Currently, I'm doing this:
for ($i=0;$i<$count;$i++)
{
$classObject = $classObjects[$i];
echo $i . " : " . memory_get_usage(true) . "\n";
$classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);
$class = $parser->parseClassInfo($classDOM);
$dbmanager->storeClassInfo($class);
unset($classDOM,$class,$classObject);
}
Can I do something like
for ($i=0;$i<$count;$i++)
{
$classObject = $classObjects[$i];
echo $i . " : " . memory_get_usage(true) . "\n";
try
{
$classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);
$class = $parser->parseClassInfo($classDOM);
$dbmanager->storeClassInfo($class);
unset($classDOM,$class,$classObject);
}
catch (Exception $e)
{
//log the error here
continue;
}
}
The code above doesn't work for fatal exceptions.
Would it be possible to do something like this:
If I moved the main loop into a method, and then call the method from register_shutdown_function ?
Like this:
function do($start)
{
for($i=$start;$i<$count;$i++)
{
//do stuff here
}
}
register_shutdown_function('shutdown');
function shutdown()
{
do();
}
This is the message that is output when execution stops:
Fatal error: Call to a member function find() on a non-object in ...
I expect this above message when a page isn't parse-able by the method I am using. I'm fine with just skipping that page and moving on to the next iteration of the loop.
Fatal errors are fatal and terminate execution. There is no way around this if a fatal error occurs. However, your error:
Fatal error: Call to a member function find() on a non-object in ...
is entirely preventable. Just add a check to make sure you have an instance of the correct object, and if not, handle the error:
if ($foo instanceof SomeObject) {
$foo->find(...);
} else {
// something went wrong
}
First, there is a distinct difference between exceptions and errors. What you encountered is an error, not an exception. Based on your message and the code you posted the problem is with something you haven't put into your question. What variable are you trying to call find() on? Well, that variable isn't an object. There is no way to trap fatal errors and ignore it, you must go find where you are calling find() on a non-object and fix it.
Seems to me like the only possible way to "catch" a faltal error is with the registering a shutdown function. Remember to add all (or maybe groups of) queries into transactions and maybe roll them back if something fails, just to ensure consistency.
I have had a similar problem to this, and I found that using a is_object() call before the find() call allows you to avoid the fatal error.