Domanda

Let's say I have an RPC call for adding colors. A user can only add colors once. If they add one a second time, I want to return an error response that tells them they screwed up, and why.

The JSON-RPC error response describes an error object that includes a space for a data parameter. It is in here that it seems appropriate to include my error code for "color already added". However, I cannot figure out how to return this in the response.

$jsonRpc = new Server();
$jsonRpc->setClass(new Testi());
$jsonRpc->getRequest()->setVersion(Server::VERSION_2);

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    echo $jsonRpc->getServiceMap()->setEnvelope(Smd::ENV_JSONRPC_2);
}
else {
    $jsonRpc->handle();
}


class Testi {

    const ERROR_CODE_COLOR_EXISTS = 5;

    private $colors = ['red', 'green'];

    /**
     * @param $color
     * @return array
     */
    public function addColor($color) {
        if (in_array($color, $this->colors)) {
            throw new \Exception('Color exists');
        }
        else {
            $this->colors[] = $color;
        }

        return $this->colors;
    }
}

This works, to the degree that an error response is returned, but gives me no option to include my error code (self::ERROR_CODE_COLOR_EXISTS).

{"error":{"code":-32000,"message":"Color exists","data":{}},"id":"","jsonrpc":"2.0"}

How do I put info into that DATA parameter!?

Thanks, Adam

È stato utile?

Soluzione

Turns out you have two choices to do this:

1) Add parameters to an exception:

$e = new Exception('I pooped my pants');
$e->color = 'brown';
$->smell = 'bad';

color and smell would then be in the data parameter of the error response.

2) Pass the server (in my code, $jsonRpc) into the object (in my code, it would look something like: new Testi($jsonRpc)), and use the fault(...) method, which allows you to pass the data array/object into it.

The latter approach gives you more flexibility as you can do data->code, data->message, neither of which can you set on the $e object, because they are existing, protected parameters. But you are then coupling your model to the $jsonRpc server, which is not good.

All that being said, it's not the correct way to respond to the scenario I outlined above. The error response is more or less reserved for true, unrecoverable server errors, akin to real exceptions, not user validation errors. In my case it was better to define a response type that allows me to return success/fail values with appropriate response codes. {success: false, code: 5}.

Cheers, Adam

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top