I'm using the amqp extension in pecl 1.0.3, compiled with 2.7.1 rabbitmq.
I'm trying to get a basic consumer/producer example working, but I keep getting errors. There's very little php documentation on this extension and a lot of it seemed to be outdated or wrong.
I used the code a user posted, but can't seem to get the consumer part working
Connection:
function amqp_connection() {
$amqpConnection = new AMQPConnection();
$amqpConnection->setLogin("guest");
$amqpConnection->setPassword("guest");
$amqpConnection->connect();
if(!$amqpConnection->isConnected()) {
die("Cannot connect to the broker, exiting !\n");
}
return $amqpConnection;
}
Sender:
function amqp_send($text, $routingKey, $exchangeName){
$amqpConnection = amqp_connection();
$channel = new AMQPChannel($amqpConnection);
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
$exchange->setType("fanout");
if($message = $exchange->publish($text, $routingKey)){
echo "sent";
}
if (!$amqpConnection->disconnect()) {
throw new Exception("Could not disconnect !");
}
}
Receiver:
function amqp_receive($exchangeName, $routingKey, $queueName) {
$amqpConnection = amqp_connection();
$channel = new AMQPChannel($amqpConnection);
$queue = new AMQPQueue($channel);
$queue->setName($queueName);
$queue->bind($exchangeName, $routingKey);
//Grab the info
//...
}
Then sending it:
amqp_send("Abcdefg", "action", "amq.fanout");
And Receiving it:
amqp_receive("amq.fanout","action","action");
I keep getting a problem running the script and points to the amqp receive:
PHP Fatal error: Uncaught exception 'AMQPQueueException' with message 'Server channel error: 404, message: NOT_FOUND - no queue 'action' in vhost '/'' in /home/jamescowhen/test.php:21
Can anyone point me to the right direction? The whole sample is from a user note here:
http://www.php.net/manual/en/amqp.examples.php#109024
The exception seems to be caused by your queue not being declared (as the error message describes 404 - the queue 'action' was not found). The reason why the example works for the original poster is probably because he already has declared the queue earlier, without realizing that it's missing in his example.
You can declare the queue by calling ->declare() on the queue object. You'll also have to do this with the exchange object, unless you're certain that it already exists when you attempt to hook the queue onto it.
Related
I am trying to connect to a service bus queue in Microsoft Azure using PHP, using the following code found on the Azure guide:
<?php
require_once 'vendor/autoload.php';
use MicrosoftAzure\Storage\Queue\QueueRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Queue\Models\CreateMessageOptions;
$connectionString = "DefaultEndpointsProtocol=https;AccountName="name";AccountKey=key";
// Create queue REST proxy.
$queueClient = QueueRestProxy::createQueueService($connectionString);
try{
// Create message.
$builder = new ServicesBuilder();
$queueClient->createMessage("cmps297r1", "Hello World!");
}
catch(ServiceException $e){
// Handle exception based on error codes and messages.
// Error codes and messages are here:
// http://msdn.microsoft.com/library/azure/dd179446.aspx
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
?>
However, when I run it, I get this error:
Catchable fatal error: Argument 4 passed to MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy::__construct() must be an instance of MicrosoftAzure\Storage\Common\Internal\Serialization\ISerializer, array given, called in /Applications/XAMPP/xamppfiles/htdocs/297R/vendor/microsoft/azure-storage/src/Queue/QueueRestProxy.php on line 110 and defined in /Applications/XAMPP/xamppfiles/htdocs/297R/vendor/microsoft/azure-storage/src/Common/Internal/ServiceRestProxy.php on line 77
The code you pasted looks fine to me (except that you didn't include use statement for ServicesBuilder class which would cause an "Class not found" error).
And as #Thuan Ng mentioned the code above belongs to Azure Storage Queue, not Service Bus Queue. You need to refer to this documentation How to use Service Bus queues with PHP if you are using Azure Service Bus.
I Know this is an old Post but you are trying to create a storage queue and not a service bus queue
Pretty new to laravel, so I'm not exactly sure how it handles errors and how best to catch them.
I'm using a 3rd party game server connection library that can query game servers in order to pull data such as players, current map etc..
This library is called Steam Condenser : https://github.com/koraktor/steam-condenser
I have imported this using composer in my project and all seems to be working fine, however I'm having trouble with catching exceptions that are thrown by the library.
One example is where the game server you are querying is offline.
Here is my code:
public function show($server_name)
{
try{
SteamSocket::setTimeout(3000);
$server = server::associatedServer($server_name);
$server_info = new SourceServer($server->server_ip);
$server_info->rconAuth($server->server_rcon);
$players = $server_info->getPlayers();
$total_players = count($players);
$more_info = $server_info->getServerInfo();
$maps = $server_info->rconExec('maps *');
preg_match_all("/(?<=fs\)).*?(?=\.bsp)/", $maps, $map_list);
}catch(SocketException $e){
dd("error");
}
return view('server', compact('server', 'server_info', 'total_players', 'players', 'more_info', 'map_list'));
}
If the server is offline, it will throw a SocketException, which I try to catch, however this never seems to happen. I then get the error page with the trace.
This causes a bit of a problem as I wish to simply tell the end user that the server is offline, however I cannot do this if I can't catch this error.
Is there something wrong with my try/catch? Does laravel handle catching errors in this way? Is this an issue with the 3rd party library?
A couple things:
Does the trace lead to the SocketException or to a different error? It's possible that a different error is being caught before the SocketException can be thrown.
Your catch statement is catching SocketException. Are you importing the full namespace at the top of your PHP file? use SteamCondenser\Exceptions\SocketException;
Also for debugging purposes, you could do an exception "catch all" and dump the type of exception:
try {
...
}catch(\Exception $e){
dd(get_class($e));
}
If you still get the stack trace after trying the above code, then an error is being thrown before the try/catch block starts.
For a project (which is about estate properties) i have included a contact form where a visitor can contact an estate broker if the visitor is interested to buy/hire an estate property.
I am using Symfony2 and its library. For the contact mail, i am using the Swiftmailer library.
Well, i have the next code which handles the form submit. there, I create a mail object to be able to send mails. It works, but i want to provide a error resolving service if there are problems with the smtp host from sender/receiver.
Here is the code,
$data = $contactForm->getData();
try {
// create body text
$body = $app['twig']->render('mailTemplate.twig', array('data' => $data, 'immoid' => $immoID));
// set mail
$mail = \Swift_Message::newInstance()
->setSubject('Contact reaction on your immo offer.')
->setFrom($app['swiftconfig']['sender'])
->setTo($contactinfo['contactmail'])
->setBody($body, 'text/html');
// send mail
$app['mailer']->send($mail);
// redirect if successfull
$app->redirect($app['url_generator']->generate('immoDetail', array('immoID' => $immoID)));
}
catch (Swift_TransportException $STe) {
// logging error
$string = date("Y-m-d H:i:s") . ' - ' . $STe->getMessage() . PHP_EOL;
file_put_contents("errorlog.txt", $string, FILE_APPEND);
// send error note to user
$errorMsg = "the mail service has encountered a problem. Please retry later or contact the site admin.";
}
catch (Exception $e) {
// logging error
$string = date("Y-m-d H:i:s") . ' - GENERAL ERROR - ' . $e->getMessage() . PHP_EOL;
file_put_contents("errorlog.txt", $string, FILE_APPEND);
// redirect to error page
$app->abort(500, "Oops, something went seriously wrong. Please retry later !");
}
($app['swiftconfig']['sender'] = mailaddress from host / $contactinfo['contactmail'] = mailaddress from site visitor (submitted in contact form))
Now, when the smtp host doesn't work, Swiftmailer DOES send an exception, but the try-catch block ISN'T catching it. The function is just being continued.
Even the root try-catch block (in app.php) isn't catching it too. As a result of this, you see a large PHP error on the webpage, which shouldn't happen. The message from it is described here below,
SCREAM: Error suppression ignored for
---
Fatal error: Uncaught exception 'Swift_TransportException' with message ' in C:\...\vendor\swiftmailer\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php on line 266
---
Swift_TransportException: Connection could not be established with host <output omitted>
Does anyone know why the try catch block isn't catching the custom exception ? I have investigated the class files and the progress, but i don't see any unusual activity.
I hope that someone can come with a solution to this because PHP errors shouldn't appear on site pages.
remove from your config.yml
spool: { type: memory }
Then you will be to add try catch like this
try{
$mailer = $this->getMailer();
$response = $this->getMailer()->send($message);
}catch(\Swift_TransportException $e){
$response = $e->getMessage() ;
}
Try to put a backslash infront of Exception.
catch(\Exception $e)
A \ (backslash) before the beginning of a class name represents the Global Namespace.
Using a backslash will ensure that the Exception is called within the global namespace.
When you do $app['mailer']->send($mail); the email message is not being sent at that point if you have spooling turned on. See http://symfony.com/doc/current/cookbook/email/spool.html
If you have the default setting of spool: { type: memory }, the \Swift_TransportException will be thrown during the kernel termination phase, after you controller has exited.
One way around this is to turn off the spooling (but then your users might have to wait while the email is sent), or you can make your own eventlistener to handle the exception. http://symfony.com/doc/current/cookbook/service_container/event_listener.html
I ran into this problem in Laravel 4.2 when I added a SwiftMailerHandler to Monolog so it would email to me anything logged at a certain level or above. There was no way for me to catch the exception in the handler and it was thrown back to the browser. I solved it by subclassing SwiftMailerHandler:
<?php
/*******************************************************************************
* $Id: LogMailer.php 12152 2015-09-15 00:42:38Z sthames $ */
/**
* Subclass of Monolog SwiftMailerHandler that will catch exceptions SwiftMailer
* throws during the send. These exceptions are logged at the critical level.
* Without this, such exceptions are reported back to the browswer.
*******************************************************************************/
class LogMailer extends \Monolog\Handler\SwiftMailerHandler
{
/** Flag set when logging an exception during send. */
protected $dont_mail = false;
/** Overloads sender to catch and log errors during the send. */
protected function send($content, array $records)
{
try
{
if (!$this->dont_mail)
parent::send($content, $records);
}
catch(\Exception $e)
{
$this->dont_mail = true;
Log::critical($e->getMessage());
$this->dont_mail = false;
}
}
}
This handler catches the SwiftMailer exception and logs it at the critical level so it's not lost. I don't get an email about it but at least it's in the log.
I was surprised to find SwiftMailerHandler offered no way to inject an exception handler into the send method but fortunately the code is written well enough to make this solution pretty simple.
Works great and has given me no trouble so far.
Sure you have the latest version of swiftmailer? Line 226 of StreamBuffer.php doesn't throw any exception. This version from 2 years ago does throw the exception on that specific line.
I'd try running the latest version before diving into the issue more deeply.
SCREAM is a setting of XDebug that allows to see errors that are normally caught or suppressed. (Using #, for example.) Search for
xdebug.scream = 1
in your php.ini and set this to 0.
you can try below code for custom error:
public function render($request, Exception $exception)
{
if ($exception instanceof \Swift_TransportException) {
return response()->view('errors.404');
}
return parent::render($request, $exception);
}
I have a loop that checks for the existence of urls. If one does not exist Selenium exits:
XHR ERROR: URL = http://localhost/pages/156.php Response_Code = 404 Error_Message = Not Found.
If i catch the exception:
try {
$this->selenium->open($url);
}
catch(PHPUnit_Framework_Exception $e) { echo "caught\n"; }
Anything i do afterwards gives me this error:
ERROR Server Exception: sessionId should not be null; has this session been started yet?
I even tried to set the exception as expected:
$this->selenium->setExpectedException('PHPUnit_Framework_Exception');
But still the session is stopped and the test is completed. How can i make Selenium keep testing the urls? Thanks.
Create new selenium instance for every url!
$this->selenium = new Testing_Selenium("*firefox", "http://your-app-under-test.org/");
$result = $this->selenium->start();
$this->selenium->open("/the-page-to-test.php");
or see http://pear.php.net/package/Testing_Selenium/docs/0.4.3/Selenium/Testing_Selenium.html#method__construct for reference, there are more arguments to the constructor.
I am writing a web app which will allow the user to specify a URL for a SoapClient. I wanted to validate that php can connect to the client when the user submits a form. I thouhgt I could do this via try catch or set_error_handler (or some combination of the two). However it looks like this is not possible for fatal errors. Is there a way to get SoapClent to test a URL which won't throw an unrecoverable error?
Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/wibble'
I want it to flag an error as the URL doesn’t exist, but I would like to be able to catch it.
Otherwise I suppose I could try to download and validate the URL myself, but I would have thought that it would be possible to do it from the SoapClient.
Should this be a fatal error?
Edit
After reading rogeriopvl's answer I reaslise that I should have said that I had tried the 'exceptions' option to the soapclient constructor and (in desperation) the use-soap-error-handler function.
Are you using xdebug? According to this PHP bug report and discussion, the issue has been fixed at least since PHP 5.1, but this xdebug bug messes with 'fatal error to exception conversions' in a way that the exception is not generated and the fatal error 'leaks through'.
I can reproduce this locally, with xdebug enabled:
try {
$soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
$exceptionMessage = t($e->getMessage());
print_r($exceptionMessage);
}
This gives me the fatal error you described, without even entering the catch clause:
Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'
It works if I disable xdebug right before the call:
xdebug_disable();
try {
$soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
$exceptionMessage = t($e->getMessage());
print_r($exceptionMessage);
}
This triggers the exception as expected, and I get a proper SoapFault Object in the catch clause with a message of:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'
So basically exceptions work as advertised. If they don't work in your case, you might encounter the xdebug bug, or maybe a similar issue with another 3rd party component.
Quoting SoapClient documentation:
The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.
So you should try something like:
$client = new SoapClient("some.wsdl", array('exceptions' => TRUE));
This way will throw SoapFault exceptions allowing you to catch them.
See: http://bugs.xdebug.org/view.php?id=249
Possible solution:
Index: trunk/www/sites/all/libraries/classes/defaqtoSoapClient.class.php
===================================================================
--- classes/defaqtoSoapClient.class.php
+++ classes/defaqtoSoapClient.class.php
## -31,10 +31,23 ##
try {
+ // xdebug and soap exception handling interfere with each other here
+ // so disable xdebug if it is on - just for this call
+ if (function_exists('xdebug_disable')) {
+ xdebug_disable();
+ }
//Create the SoapClient instance
parent::__construct($wsdl, $options);
}
catch(Exception $parent_class_construct_exception) {
+ if (function_exists('xdebug_enable')) {
+ xdebug_enable();
+ }
// Throw an exception an say that the SOAP client initialisation is failed
throw $parent_class_construct_exception;
+ }
+ if (function_exists('xdebug_enable')) {
+ xdebug_enable();
}
}
you could try and do a curl or fsockopen request to check the URL is valid.
For your information, i'm using SoapClient with PHPUnit to test remote WebServices and got the same problem!
when using an old PHPUnit version (3.3.x) as third party, phpunit crash
when using current version of PHPUnit (3.4.6) as third party, phpunit display "RuntimeException".
Here is my first test method :
public function testUnavailableURL() {
$client = new SoapClient("http://wrong.URI");
}
Here is PHPUnit first result :
There was 1 error:
1) MyTestCase::testUnavailableURL
RuntimeException:
FAILURES!
Here is my second test method :
public function testUnavailableURL() {
try {
$client = #new SoapClient("http://wrong.URI");
} catch (SoapFault $fault) {
print "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})";
}
}
Here is PHPUnit second test result :
PHPUnit 3.4.6 by Sebastian Bergmann.
.SOAP Fault: (faultcode: WSDL, faultstring: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://wrong.URI' : failed to load external entity "http://wrong.URI"
)...
Time: 3 seconds, Memory: 4.25Mb
OK
NB: i found a phpunit ticket on this subject : ticket 417