Question

I have php code that execute python cgi and I want to pass python trace (returned from cgi) as extra data to php exception how can I do this and how can I get that value from catch(Exception e) { (It should check if that extra value exesit or not).

I have code like this:

$response = json_decode(curl_exec($ch));
if (isset($response->error)) {
    // how to send $response->trace with exception.
    throw new Exception($response->error);
}
return $response->result;

and I use json-rpc library that should return that data to the user:

} catch (Exception $e) {
    //catch all exeption from user code
    $msg = $e->getMessage();
    echo response(null, $id, array("code"=>200, "message"=>$msg));
}

Do I need to write new type of exception or can I do this with normal Exception? I would like to send everything that was thrown in "data" =>

Was it helpful?

Solution

You need to extend Exception class:

<?php

class ResponseException extends Exception 
{
    private $_data = '';

    public function __construct($message, $data) 
    {
        $this->_data = $data;
        parent::__construct($message);
    }

    public function getData()
    {
        return $this->_data;
    }
}

When throwing:

<?php

...
throw new ResponseException($response->error, $someData);
...

And when catching:

catch(ResponseException $e) {
    ...
    $data = $e->getData();
    ...
}

Dynamic Property (not recommended)

Please note that this will cause deprecation error in PHP 8.2 and will stop working in PHP 9 according to one of the PHP RFC https://wiki.php.net/rfc/deprecate_dynamic_properties

As the OP asking about doing this task without extending Exception class, you can totally skip ResponseException class declaration. I really not recommend do it this way, unless you've got really strong reason (see this topic for more details: https://softwareengineering.stackexchange.com/questions/186439/is-declaring-fields-on-classes-actually-harmful-in-php)

In throwing section:

...
$e = new Exception('Exception message');
$e->data = $customData; // we're creating object property on the fly
throw $e;
...

and when catching:

catch(Exception $e) {
    $data = $e->data; // Access data property
}

September 2018 edit: As some of readers found this answer useful, I have added a link to another Stack Overflow question which explains the downsides of using dynamically declared properties.

OTHER TIPS

Currently, your code converts the response text directly into an object without any intermediate step. Instead, you could always just keep the serialized (via JSON) text it and append it to the end of the Exception message.

$responseText = curl_exec($ch);
$response = json_decode($responseText);
if (isset($response->error)) {
    throw new Exception('Error when fetching resource. Response:'.$responseText);
}
return $response->result;

Then you could just recover everything after "Response:" in your error log and optionally de-serialize it or just read it.

As an aside, I would also not count on the server sending JSON, you should verify that the response text was actually parseable as JSON and return a separate error for that if it isn't.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top