Giter VIP home page Giter VIP logo

Comments (13)

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

That's actually not a bad idea. When we built the first version, the idea was to push something into the open rapidly, so that people can start building stuff. If you have a working patch, please generate a pull request and I'll examine how to integrate it in.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

Technically speaking, the easiest would be to do something like this:

    public function   applications_list()
    {
        try {

            if (is_null($this->pestObject))
                throw new Exception("PEST Object not provided or is null", 503);

            $uri = "/applications";
            $result = $this->pestObject->get($uri);

            return $result;


        } catch (Exception $e) {
           die("Exception raised: " . $e->getMessage() . "\nFile: " . $e->getFile() . "\nLine: " . $e->getLine());
        }
    }

In this methodology, your script will simply blow up in your face, spitting out the error message right in your face. Personally, I hate when scripts terminate like that, it gives me bad memories from the nights I used to code too much JAVA.

However, I think that probably holding a last_error public variable could come in handy, something that would hold the last error message, which can be retrieved in a case where the last request failed.

What do you think?

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

I've created a new branch called "enhanced-exception-handling". Basically, I've added a public variable to "asterisk" and "applications" module, that will hold the last Exception that was raised within a method.

The concept is simple - if you got a FALSE result, simply check the contents of $last_error in order to get your Exception object.

For example:

    $conn = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT); //create new object
    $app  = new applications($conn);

    header('Content-Type: application/json');
    $applist = $app->applications_list();

    if (!$applist) 
       vardump($app->last_error)
   else 
       echo json_encode($applist);

Again, just a concept.

from phpari.

stgnet avatar stgnet commented on June 8, 2024

The response to a connection failure should be the same as the underlying ReactPHP library.

If I use their http-client example and have it request from an invalid URL, the $request->on('end', function()) is passed a string describing the exception ' exception 'React\SocketClient\ConnectionException' with message 'Connection refused' in (...)/Connector.php:74' complete with a stack trace.

This is ostensibly to allow the event loop to continue running, while still being able to report full debug information via whatever method it chooses.

This library should do something similar -- allow you to specify a callback function along the same lines of request->on(event,func()) that provides error handling.

The library itself should however never execute exit() or die(), since it takes away the user's ability to handle errors themselves, and makes presumptions about the error output format (i.e. should it be text, or html, or ??).

As I continue working with this I will have some further suggestions.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

Hey Scott,

Previously, you've remarked regarding the PEST library - but hadn't responded to my query.

Nir

from phpari.

stgnet avatar stgnet commented on June 8, 2024

I'm still working through how best to formulate a stasis app event loop. Ideally that would use the React event loop, possibly at the cost of requireing some other changes. Once I've figured that out I'll get back to you with a solid recommendation.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

Tried replicating the issue you've indicated, regarding not having StasisStart work - here is a sample I've made that shows that it is being accepted:

    class BasicAriConnector
    {
        public function __construct()
        {
            $phpariObject = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT);

            $this->ariEndpoint  = $phpariObject->ariEndpoint;
            $this->stasisClient = $phpariObject->stasisClient;
            $this->stasisLoop   = $phpariObject->stasisLoop;
            $this->stasisLogger = $phpariObject->stasisLogger;
        }

        public function handlers()
        {
            try {
                $this->stasisClient->on("request", function ($headers) {
                    $this->stasisLogger->notice("Request received!");
                });

                $this->stasisClient->on("handshake", function () {
                    $this->stasisLogger->notice("Handshake received!");
                });

                $this->stasisClient->on("message", function ($message) {
                    $messageObject = json_decode($message->getData());
                    echo $messageObject->type . " Received \n";
                });

            } catch (Exception $e) {
                echo $e->getMessage();
                exit(99);
            }
        }

        public function execute()
        {
            try {
                $this->stasisClient->open();
                $this->stasisLoop->run();

            } catch (Exception $e) {
                echo $e->getMessage();
                exit(99);
            }
        }

    }

    $basicAriClient = new BasicAriConnector();

    /**
     * Get some basic information from ARI
     */
    $basicAriClient->handlers();
    $basicAriClient->execute();

    exit(0);

The output looks like this:

$ php BasicAriConnector.php
2014-10-05T21:17:31+02:00 NOTICE (5): Request received!
2014-10-05T21:17:31+02:00 NOTICE (5): Handshake received!



StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received

I've used a simple dialplan that activates Stasis and the program it self is very straight forward.

It is using the React event loop, phpari simply hides most of it from the developer - making it a fairly straight forward task.

from phpari.

stgnet avatar stgnet commented on June 8, 2024

If you're running Asterisk on the same machine as PHP, you likely won't see
the issue manifest. It's a race condition which may not appear always in
different network conditions.

The Asterisk system I'm testing against is on a cloud (vps) server. I can
get you an account to play with on that box if you wanted to. Once I
applied the fix I wrote up the issue disappears. It's a flaw in the
handshake validation of the phpws library.

I'm working on a two examples - one a simple answer, playback, hangup, and
another with a more complicated stasis app with some interactive components.

I have some recommendations on how to improve the phpari library, which I
will share with you in detail later. The first is simply to consider that
there are two types of usage for the library - a rest client only model
where a few requests are made and that's it, and a stasis app with event
loop model where the app registers as a stasis app with a specific name (or
multiple apps with separate names), hangs around for a long time on the
event loop, and issues rest calls back to initiate actions as a reaction to
those events. The former does not need the react event loop, websocket
connection, or stasis app name in the constructor. But it should be
possible to have multiple stasis apps with separate names operating under a
single react event loop. My recommendation to achieve this is to break out
the stasis app functions as a separate class instance, say $app =
$phpari->stasisApp('app_name', $loop);.

Hiding the react loop as a default stasisApp('nameonly') is a good idea,
but one of the design constraints of an cooperative tasking event loop is
that you can only have one. Thus they recommend that libraries allow an
externally instantiated event loop to be passed in.

_------------------------------ Scott Griepentrog +1-_317-644-2228

Software Telephony Group http://stg.net/
{
"fullName" : "Scott Griepentrog",
"email" : "[email protected]",
"phone" : "tel:+13176442228",
"sip" : "sip:[email protected]",
"company" : "Software Telephony Group",
"website" : "http://stg.net",
"twitter" : "@stgnet",
"google+" : "http://google.com/+scottgriepentrog",
"linkedIn" : "http://linkedin.com/in/stgnet",
"tags" : ["software development","asterisk","telecom","voip"]
}

On Sun, Oct 5, 2014 at 2:21 PM, Nir Simionovich [email protected]
wrote:

Tried replicating the issue you've indicated, regarding not having
StasisStart work - here is a sample I've made that shows that it is being
accepted:

class BasicAriConnector
{
    public function __construct()
    {
        $phpariObject = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT);

        $this->ariEndpoint  = $phpariObject->ariEndpoint;
        $this->stasisClient = $phpariObject->stasisClient;
        $this->stasisLoop   = $phpariObject->stasisLoop;
        $this->stasisLogger = $phpariObject->stasisLogger;
    }

    public function handlers()
    {
        try {
            $this->stasisClient->on("request", function ($headers) {
                $this->stasisLogger->notice("Request received!");
            });

            $this->stasisClient->on("handshake", function () {
                $this->stasisLogger->notice("Handshake received!");
            });

            $this->stasisClient->on("message", function ($message) {
                $messageObject = json_decode($message->getData());
                echo $messageObject->type . " Received \n";
            });

        } catch (Exception $e) {
            echo $e->getMessage();
            exit(99);
        }
    }

    public function execute()
    {
        try {
            $this->stasisClient->open();
            $this->stasisLoop->run();

        } catch (Exception $e) {
            echo $e->getMessage();
            exit(99);
        }
    }

}

$basicAriClient = new BasicAriConnector();

/**     * Get some basic information from ARI     */
$basicAriClient->handlers();
$basicAriClient->execute();

exit(0);

The output looks like this:

$ php BasicAriConnector.php
2014-10-05T21:17:31+02:00 NOTICE (5): Request received!
2014-10-05T21:17:31+02:00 NOTICE (5): Handshake received!

StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received

I've used a simple dialplan that activates Stasis and the program it self
is very straight forward.

It is using the React event loop, phpari simply hides most of it from the
developer - making it a fairly straight forward task.


Reply to this email directly or view it on GitHub
#17 (comment)
.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

Actually, I'm running my Asterisk server on a cloud server at DigitalOcean - and the Stasis app is running from my Home machine - a few thousands miles away :-)

I see your point regarding the stasis app. Technically speaking, you really don't need the React in order to initiate the PEST objects, that is correct.

I'm waiting to see your recommendations regarding react :-)

from phpari.

stgnet avatar stgnet commented on June 8, 2024

So, either a fluke that I found that, or possibly because I'm running trunk
(as in asterisk 14). Would have tripped somebody up at some point to be
sure.

I'm going to get my app completely coded and functional before I start
sending you specifics so that it's based on proven working code.

_------------------------------ Scott Griepentrog +1-_317-644-2228

Software Telephony Group http://stg.net/
{
"fullName" : "Scott Griepentrog",
"email" : "[email protected]",
"phone" : "tel:+13176442228",
"sip" : "sip:[email protected]",
"company" : "Software Telephony Group",
"website" : "http://stg.net",
"twitter" : "@stgnet",
"google+" : "http://google.com/+scottgriepentrog",
"linkedIn" : "http://linkedin.com/in/stgnet",
"tags" : ["software development","asterisk","telecom","voip"]
}

On Sun, Oct 5, 2014 at 4:05 PM, Nir Simionovich [email protected]
wrote:

Actually, I'm running my Asterisk server on a cloud server at DigitalOcean

  • and the Stasis app is running from my Home machine - a few thousands
    miles away :-)

I see your point regarding the stasis app. Technically speaking, you
really don't need the React in order to initiate the PEST objects, that is
correct.

I'm waiting to see your recommendations regarding react :-)


Reply to this email directly or view it on GitHub
#17 (comment)
.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

Well,

Looks like I just experienced the same thing you've described. It seems a little transient or something, as I can't always re-produce it.

I've devised a very nice Stasis application example.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024
  • Added error handling using "lasterror" and "lasttrace" variables in the phpari object, you can use that for error checking.
  • Modified the phpari class to enable proper buildup of PHP events callback - see BasicStasisApplication.php file for additional information.

from phpari.

greenfieldtech-nirs avatar greenfieldtech-nirs commented on June 8, 2024

This is now being handled properly and had been regressed.

Thanks for the heads up @stgnet

from phpari.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.