I'm trying to interact with an Azure Queue using a REST proxy courtesy of the Windows Azure SDK for PHP. Whilst there are plenty of code samples here, I want to check whether a queue exists so that I can create it if necessary, before adding a message to it.
try {
// setup connection string for accessing queue storage
$connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;
// create queue REST proxy
$queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);
// create message
$queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');
} catch(ServiceException $e){
// Handle exception based on error codes and messages.
// Error codes and messages are here:
// http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
Creating a queue is as simple as this...
$queueRestProxy->createQueue(QUEUE_NAME);
Should I simply include the queue creation code prior to creating a message or is there a more efficient way to ascertain whether the queue exists before interacting with it?
Normally in other Windows Azure SDKs I have seen methods like createQueueIfNotExists and I'm surprised that this method is missing from PHP SDK. Basically the way this function works is that it tries to create a queue. If the queue by the same name exists in storage, storage service throws a Conflict (409) error.
Since this function is not there, you could do the same i.e. try to create the queue inside its own try/catch block and check the error code. If the error code is 409, you continue otherwise you rethrow the exception. Something like the code below:
try {
// setup connection string for accessing queue storage
$connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;
// create queue REST proxy
$queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);
try {
// now try to create the queue.
$queueRestProxy->createQueue(QUEUE_NAME);
} catch(ServiceException $e){
$code = $e->getCode();
//Now check if the $code is 409 - Conflict. If the error code is indeed 409, you continue otherwise throw the error
}
// create message
$queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');
} catch(ServiceException $e){
// Handle exception based on error codes and messages.
// Error codes and messages are here:
// http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
P.S. I have not tried to execute the code, so it may throw errors. This is just to give you an idea.
I've posted an answer below for completeness and to make it easy for people to see the answer at a glance.
Should I simply include the queue creation code prior to creating a
message or is there a more efficient way to ascertain whether the
queue exists before interacting with it?
There are two ways to approach this...
Include the createQueue statement prior to creating a message, but wrap this statement in a try-catch block as directed by Guarav Mantri's answer i.e. ignore 409 errors, but throw an exception for any other types of error.
For information, when you include a createQueue statement prior to creating a message...
if a queue of the same name already exists and the metadata
associated with the existing queue is the same as that passed to the
createQueue statement then the queue will not be created and the
Queue REST Proxy will internally receive a 204 (No Content) status code, but this
response code is not made available to the programmer. So,
essentially, the createQueue statement doesn't cause an
error/exception to be raised in this scenario.
if a queue of the same name already exists and the metadata
associated with the existing queue isn't the same as that passed
to the createQueue statement then the queue will not be created and
the Queue REST Proxy will receive a 409 (Conflict) status code and will raise an
exception which allows the programmer to access this response code and the associated QueueAlreadyExists message.
Source: Create Queue (REST API) - see Remarks section
Create a queueExists function and call it to decide whether or not queue creation is necessary. Here is one way to implement such a function...
public function queueExists($queueRestProxy, $queueName) {
$result = FALSE;
$listQueuesResult = $queueRestProxy->listQueues();
$queues = $listQueuesResult->getQueues();
foreach($queues as $queue) {
if ($queue->getName() === $queueName) {
$result = TRUE;
break;
}
}
return $result;
}
Hope this helps someone!
Related
I'm building a full system with both Laravel and VueJS and at some point, I'm generating pictures from a list of pictures with Image Intervention.
But this process can break, there are many issues that I faced and resolved that can appear in the future.
What would you recommend me to do to have a broken code not stop the rest ? I was thinking on some service that would be called and be independent, asynchronous.
Can Laravel cover that ? I have read about events in both Laravel and Symfony but that is something I never understood.
Greetgins
Well, I was in a similar problem some days ago. Although, My problem was related to inserting data from CSV to the database. So, there were chances of having some different datatype that might generate the error and halt the whole remaining process. So, I used try catch inside my job. I will show you reference, you can modify as you wish:
$error_arr = array();
$error_row_numbers = array();
try{
//Write your code here that might throw error
$row = Model::updateOrCreate(
['id' => $id,
$Arr
);
} catch (\Exception $e) {
//Optionally you can store error message
//and image number which is failed here
$error_arr[] = $e->getMessage();
$error_row_numbers[] = $row_no; //this row_no is different variable
//and should be increased in loop
//to determine exact image
}
I wanted to test an laravel api by connecting it with android studio by asyn task but i'm getting HTTP status code 500
Here is my code in AbcController :
public function register_otpsent(Request $req)
{
// $myclass = new MyClasses();
//{cardno}, {mobileno}
$cardno = $req->input('cardno');
$mobileno = $req->input('mobileno');
//
// if(strlen($cardno)==0){
// return response()->json("Please enter valid card number !" , 400);
// }
$cnt = DB::table('acc_status')->where('cardno','=',$cardno)->count();
if($cnt==0){
return response()->json("This card number seems to be wrong !", 400);
}
$accid = DB::table('acc_status')->where('cardno','=',$cardno)->first()->accid;
$pdetails = DB::table('acc_personaldetails')->where('accid','=',$accid)->first();
if($pdetails->mobileno != $mobileno){
return response()->json("This mobile number seems to be not registered !", 400);
}
$otp = mt_rand(100000, 999999);
return response()->json($otp, 200);
}
HTTP Status Code 500 is a server side error (all 5xx are server side)
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
There could be a number of things that could be wrong, it should be basic debugging:
Does input cardno exists in the request? If it doesn't, boom, error
Does input mobileno exists in the request? If it doesn't, boom, error
Do you have use DB; on the top of the page? If it doesn't, boom, error
Do you have use Illuminate\Http\Request on the top of the page? If it doesn't, boom, error
From this piece of code only, I'm guessing it's one of these (assuming the queries are correct and the tables exist). You should try to validate the data you're receiving, otherwise you'll get unexpected results/errors.
To detect this error, you can either:
Access your log files, located in projectdir/storage/logs/laravel.log (or depending on your custom configuration)
Request it with your browser and make sure you have in your .env file, APP_DEBUG = true, so you can see the error.
Wrap the content in a try-catch and on the catch, response()->json($$exception, 200); and check the error on your android studio end
Check with Postman if you want to use POST, PUT, or any other. (that I usually use https://www.getpostman.com/)
I needed to make sure an External API call (which might take 200-300ms to respond) does not run more than once (Please see my Edit for a better explanation of what I'm trying to do).
This is what I finally thought of:
try{
// Start Transaction
$db->beginTransaction();
// UPDATE (This sets in database that API call was successful)
// Yes, before even calling the API
$stmt = $db->prepare("QUERY1");
$stmt->execute();
// Row isn't updated?
if ($stmt->rowCount() < 1){
// STOP, It might be running in another code execution (Which is what we're trying to prevent here)
throw new PDOException('Not updated!');
}
// Some External API call
$call = $external_api->action();
// External API call was "NOT" Successful?
if ($call !== TRUE){
throw new PDOException('API Failed!');
}
// UPDATE the same row again with "Real" API response data
$stmt = $db->prepare("QUERY2");
$stmt->execute();
// All good
$db->commit();
}catch(PDOException $e){
// If Something went wrong rollback!
$db->rollBack();
}
But I have 3 questions which I don't know the answer for:
Is this a good approach? or it might cause more harm than good?
What happens if PHP gets timed out and we don't roll back? will it roll back automatically if we don't commit?
In the following part of code:
// Row isn't updated?
if ($stmt->rowCount() < 1){
// STOP, It might be running in another code execution (Which is what we're trying to prevent here)
throw new PDOException('Not updated!');
}
If the rowCount is 0, it won't roll back anything right? (I don't want it to roll back the same Query for another Code Execution)
In the end, if there is a better method or approach in my case to prevent double executions, please kindly let me know.
Edit:
What I'm trying to do here, is stopping people from running this page from 2 different browsers at the same time (or refreshing too quickly) and getting the external api call inside this page executed more than once.
https://example.com/?execute_id=15
So if it goes inside if ($stmt->rowCount() < 1){...} it means this row is already updated by another execution, and by throwing execption it stops calling the following API call again.
I dunno how to explain it better :(
i am trying to write php code which would broadcast the value of a specific field in a database, whenever another page tells it to.
to give some context, i have a custom timer always open on a page, and i want the user to be able to turn this on via an external hardware switch, which updates the field in a database, and informs the server to broadcast this change, initiating the timer. if possible i would like to forego the middle man in general and have the switch tell the server to broadcast the switch value kick starting the timer.
is what i am proposing possible? I've started using Server Sent Events but havn't got the proper hang of it...
<?php
header('Content-Type: text/event-stream');
require "conf/config.php";
mysqli_report(MYSQLI_REPORT_STRICT);
try {
$con=mysqli_connect(DBSERVER,DBUSER,DBPASS,DBNAME);
} catch (Exception $exp) {
echo "<label style='font-weight:bold; color:red'>MySQL Server Connection Failed. </label>";
exit;
}
$query = 'SELECT SwitchPressed FROM live_timers WHERE Timer = 1';
$result = mysqli($con,$query);
$data = mysqli_fetch_assoc($result);
echo "data: {$data}\n\n";
flush();
And i have this in my controller,
var Events = new EventSource('latch.php');
Events.onmessage = function(event) {
console.log(event.data);
};
just testing if stuff works, unfortunately like this i get no messages... thanks in advance for any help
In the MDN doc, they use a while loop that never ends (because it's a stream)
Im using a php web form to insert product registrations into a .NET published web service. My insertXmlData function works, but I'm having trouble with error handling. When I attempted to insert a record with an already existing serial number Im getting this returned:
ERROR-5002 - Unique serial number must not be blank System.Exception
I tried this:
try
{
$xmlData = insertXmlData($url, $xml);
}
catch (Exception $e)
{
echo ("Triggered");
throw new Exception( 'There was an error...', 0, $e);
}
But the catch clause doesn't even trigger. Is it a .NET to php thing or is my syntax incorrect? What's my best option for handling errors in this situation?