...

View Full Version : curl_exec not catching timeout/no connection



crmpicco
09-16-2009, 11:07 AM
Fatal error: Maximum execution time of 60 seconds exceeded in C:\wamp\www\path\to\script\CRMPicco.inc.php on line 102

I am receiving this error with the following code, the domain that I am using has been removed from my hosts file for testing purposes so that I can test where there is no connection to the server for example. Does anyone know why I would be getting this error and curl_exec doesn't throw and exception which would be caught by the try block?



// create the headers
$headers = array(
"POST HTTP/1.0",
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"Content-length: ".strlen($xml)
);

// create a new cURL session
$ch = curl_init();

// set a range of options for this cURL session
curl_setopt($ch, CURLOPT_URL, "www.crmpicco.co.uk/testurl.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // timing out after 191secs
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 25);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

// send the request and store the result in an array
try {
$data = curl_exec($ch); // <-- errors here
}
catch (Exception $e) {
debug($e->getMessage());
throw new Exception("Error with cURL request");
}


Cheers,
Picco

Fou-Lu
09-16-2009, 12:16 PM
curl library is pre 5.0, and 5.0 is when exceptions were introduced to PHP.
What does that debug method do?

crmpicco
09-16-2009, 12:20 PM
The debug method just logs the exception message. But it's not getting to that stage, the code just throws a fatal error on the line I have highlighted in the code. curl works with PHP 5, I am using it on PHP 5. Is there anyway to catch the scenario where I cannot connect rather than it just dying on me?

crmpicco
09-16-2009, 12:41 PM
Any idea why this attempt would error?




protected function dispatch() {

//... code in here....

try {
$data = curl_exec($ch) or $this->connectionrefused();
} catch (Exception $e) {
debug($e->getMessage());
throw new Exception("Error with cURL request");
}

function connectionrefused() {
throw new Exception("Cannot connect to dispatcher.");
}

//... code in here....

}

Fou-Lu
09-16-2009, 12:44 PM
I didn't say that curl didn't work with PHP5, I said its pre 5.0 and cannot support exceptions, just like other php 4 libraries like mysql.
There needs to be more to it than this. I assume that this file is the CRMPicco.inc.php file correct?


For you're above, connectionRefused call does not exist in the context of $this. It is a function, not a declared method, just call it with connectionrefused instead.

SKDevelopment
09-16-2009, 01:21 PM
Your initial script (post #1) worked for me. But to return the correct data to the variable $data I had to replace the line


curl_setopt($ch, CURLOPT_URL, "www.crmpicco.co.uk/testurl.php");

with


curl_setopt($ch, CURLOPT_URL, "http://www.crmpicco.co.uk/testurl.php");


Of course I had to echo the variable $data to see the returned content (CURLOPT_RETURNTRANSFER has been set by you).

As to the "Maximum execution time of 60 seconds exceeded", are you testing from the local computer ? Could it be that your firewall is blocking the outgoing connection from your script at port 80 ? The script worked for me very quickly and without any delays.

crmpicco
09-16-2009, 01:41 PM
I am testing it on a local machine and the domain that I am using is just an example (not the real one). Not sure if I have explained this properly, but I have removed the line in my hosts file (temporarily for testing) which resolves the domain to the IP. So basically curl cannot access the URL.

Is there any way for me to check for this?



$data = curl_exec($ch) or die("Cannot access dispatcher"); // this works


However, I don't want to die. Ideally, i'd like to just throw an exception as the code is in a try block. Any ideas? The following doesn't work......



$data = curl_exec($ch) or throw new Exception; // DOESN'T work

SKDevelopment
09-16-2009, 01:57 PM
You would like to throw an exception instead of dieing ? So you could just throw it:


$data = curl_exec($ch);
if(false===$data)
{
throw new Exception("Cannot access dispatcher");
}

Or maybe I do not understand something correctly. Then please explain.

crmpicco
09-16-2009, 03:26 PM
No, unfortunately that just throws a general error. From what I have seen so far cURL doesn't seem to be working as it should do with regards to the CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT options.



curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);


I would expect that if it couldn't find the URL, couldn't connect, couldn't resolve etc, etc, then it should "timeout" or "connect timeout". But it doesn't do either. On the line:
$data = curl_exec($ch); it just keeps trying to connect, for the 60 seconds and then dies with a fatal error of:

Fatal error: Maximum execution time of 60 seconds exceeded in C:\wamp\www\path\to\script\CRMPicco.inc.php on line 102 (the curl_exec line is line 102).

Any help on this would be really appreciated.

crmpicco
09-17-2009, 01:45 PM
For some reason the code appears to be getting called time and time again until the max script execution time gets hit then it throws a fatal error. This must be something to do with cURL - but I can't identify what the issue is. Is it something to do with initialising a cURL session?

Is it not possible for me to just stop code execution silently after the line: throw new Exception("constructor exception"); ?



class PiccolaxCtrl {

function __construct($type="sale") {

...code....

try {
$this->dispatch();
} catch (Exception $e) {
throw new Exception("constructor exception");
}

}

protected function dispatch() {

// create a new cURL session
$ch = curl_init();

$data = curl_exec($ch);

if (empty($data)) {
throw new Exception("Cannot access the dispatcher");
}
}
}

crmpicco
09-17-2009, 04:09 PM
I managed to find a solution to this without having to use exceptions and the like. Please see the code below, I hope it can be of help to someone researching this code at some point in the future:




protected function dispatch() {

// .... code ....

$dispatcher_conn_issue = false;

// send the request off to Sabrix
$data = curl_exec($ch);

// check if we cannot find the host
if (empty($data)) {
// set a flag to donate a connection issue
$dispatcher_conn_issue = true;

$picco_info["status"] = "Failure";
$picco_info["statusinfo"] = "Failed Request";

}

if (!$dispatcher_conn_issue) {

// ... rest of my code ...

}

$this->piccoval = $picco_info; // member variable set here

}

Fou-Lu
09-17-2009, 04:56 PM
Glad you got it worked out.
As for you're question of silent shutdown, that is dependent on you're main handling. Since the construct method has a potential of tossing the exception, you'd need to gracefully handle it in you're call:


try
{
$mycurl = new PiccolaxCtrl();
}
catch (\Exception $ex)
{
print 'Something bad happened, we need to stop';
}

Or continue off of that. PHP lacks two things I wish it had, the finally clause and checked exceptions. Checked exceptions are like so:


class MyClass
{
public void myMethod() throws Exception
{
}
}

(Thats java, but close enough). Checked exceptions force you to try catch at compile time since it has the potential of throwing an exception.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum