1

I'm trying to create a library for a personal project using php sockets. For that I started using phpUnit, to learn and to write a (more or less) qualitative library.

When i don't provide the try/catch block in the testConnection method, php gives an error that the connection has timed out (wich is normal, 'cause the device isn't connected). But php should handle the exception in the execute method below, not in the testConnection method. And I can't seem to figure this out.

This is the error:

PHPUnit_Framework_Error_Warning : stream_socket_client(): unable to connect to tcp://x.x.x.x:* (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.)

Testclass with method and try/catch that should not be there:

public function testConnection() {
    $adu = new Adu();
    $adu->setPort('AS0');
    $adu->setData('?');

    $command = new Command('x.x.x.x', *);
    $command->setAduSent($adu);

    try
    {
        $command->execute();
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
    }
}

This (the execute method) is where the Exception should be handled:

public function execute()
{
    try {
        $this->stream = $this->createStream($this->address, $this->port, $this->timeout);
    }
    catch(Exception $e) {
        $this->logger->error('Exception (' . $e->getCode() . '): ' . $e->getMessage() . ' on line ' . $e->getLine(), $e);
    }

    $this->send($this->stream, $this->aduSent);
    $this->aduReceived = $this->receive($this->stream);
}

private function createStream($address, $port, $timeout = 2)
{
    $stream = stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);

    if(!$stream) {
        throw new Exception('Failed to connect(' . $errorCode . '): ' . $errorMessage);
    }

    return $stream;
}

Solution

Because a try/catch won't catch errors/warnings I had to suppress the warnings triggered by the stream_socket_client. An then check if the return value is false or a stream object. If false, throw an appropriate Exception.

$stream = @stream_socket_client('tcp://' . $address . ':' . $port, $errorCode, $errorMessage, $timeout);
glenz0r
  • 53
  • 7

1 Answers1

2

The stream_socket_client sentence produces a warning, not an Exception, and warnings are not captured by try / catch blocks.

But PHPUnit do capture warnings, and throws an Exception in that case, so an error is triggered. You can configure PHPUnit not to consider warnings as errors, although I would not recommend it. Your code should be warnings free. PHPUnit docs.

gontrollez
  • 6,372
  • 2
  • 28
  • 36
  • Tnx for the info! But how can i avoid the warning? Because it is something to keep in mind, that the connection could not be established. Unless i don't use stream_socket_client and write the socket from scratch. And check whether there is a timeout and then throw an exception myself, if that's possible. – glenz0r May 19 '14 at 21:28