0

I run a bunch of servers that I monitor on a minutely basis from another server. The relevant bit of code goes like this

$ctx = stream_context_create(array('http'=>array('timeout'=>10)));
try
{
 $mei = file_get_contents("https://url/status.php?key=shhh",false,$ctx);
} catch(Exception $e) 
{
 trigger_error($e->getMessage());
 $mei = null;
}   
        

I started providing a stream context when I realized that if one of the monitored servers is down the whole setup stops working and returns a 504, Bad Gateway, error.

Everything good so far. What puzzles me is this - for some reason the 10s timeout is triggering an error message in my Nginx log file but I am unable to catch the exception in my code above. I should mention that this is NOT and error_reporting issue. I checked my error_reporting settings and, for good measure, tried with error_reporting(E_ALL) right at the top.

I could always just stick in an @ prior to file_get_contents and everything would be fine but this puzzles me - either I need to stop working and spot my mistake here or else there is another issue at work.

halfer
  • 19,824
  • 17
  • 99
  • 186
DroidOS
  • 8,530
  • 16
  • 99
  • 171
  • Whats your exact problem? – siddhesh May 09 '15 at 07:22
  • I think my question explains the problem adequately. However... quite simply the issue is that for some reason the catch(Exception $e) is not catching the exception thrown when the file_get_contents times out - even though I get an entry in the Nginx error.log file. – DroidOS May 09 '15 at 07:26
  • http://stackoverflow.com/questions/3431169/good-error-handling-with-file-get-contents it might be helpful to you – siddhesh May 09 '15 at 07:35
  • There's nothing in the documentation that says `file_get_contents()` throws an exception. It just returns false and logs an error or warning. You need to check the return value explicitly. In PHP an error is **not** the same as an exception. – Tangentially Perpendicular Apr 03 '22 at 10:17

2 Answers2

0

Use Guzzle or curl to verify the availability of the server prior your request the it's file_get_contents.

can be prettier but you get the point:

$server = 'https://url/status.php?key=shhh';
$client = new GuzzleHttp\Client();
$res = $client->request('GET', $server);

if ($res->getStatusCode() == 200) {
    $ctx = stream_context_create(array('http' => array('timeout' => 10)));
    try {
        $mei = file_get_contents($server, false, $ctx);
    } catch (Exception $e) {
        trigger_error($e->getMessage());
        $mei = null;
    }
}
lordisp
  • 634
  • 9
  • 21
0

In PHP (>=7) it would be better to catch \Throwable type, because it's the base class for both Error and Exception.

$ctx = stream_context_create(array('http'=>array('timeout'=>10)));
try
{
    $mei = file_get_contents("https://url/status.php?key=shhh",false,$ctx);
}
catch(\Throwable $e)
{
    trigger_error($e->getMessage());
    $mei = null;
}
shingo
  • 18,436
  • 5
  • 23
  • 42