33namespace georgique \yii2 \jsonrpc ;
44
55use yii \base \InvalidRouteException ;
6+ use yii \base \UserException ;
67use yii \helpers \Json ;
78
89/**
@@ -20,19 +21,19 @@ class Action extends \yii\base\Action {
2021 * Parses json body.
2122 * @param $rawBody
2223 * @return array
23- * @throws Exception
24+ * @throws JsonRpcException
2425 */
2526 public function parseJsonRpcBody ($ rawBody ) {
2627 try {
2728 $ parameters = Json::decode ($ rawBody , false );
2829 if (!$ parameters ) {
29- throw new Exception ('Could not parse JSON-RPC request body - empty result. ' , JSON_RPC_ERROR_REQUEST_INVALID );
30+ throw new JsonRpcException ('Could not parse JSON-RPC request body - empty result. ' , JSON_RPC_ERROR_REQUEST_INVALID );
3031 }
3132
3233 return $ parameters ;
3334 }
34- catch (Exception $ e ) {
35- throw new Exception ('Could not parse JSON-RPC request. ' , JSON_RPC_ERROR_PARSE );
35+ catch (JsonRpcException $ e ) {
36+ throw new JsonRpcException ('Could not parse JSON-RPC request. ' , JSON_RPC_ERROR_PARSE , $ e );
3637 }
3738 }
3839
@@ -43,7 +44,7 @@ public function parseJsonRpcBody($rawBody) {
4344 * @return bool|string
4445 */
4546 public function parseMethod ($ method ) {
46- if (!preg_match ('/^[\d\w_.]+$/ ' , $ method )) {
47+ if (!preg_match ('/^[\d\w_\- .]+$/ ' , $ method )) {
4748 return false ;
4849 }
4950
@@ -60,16 +61,16 @@ public function parseMethod($method) {
6061 * Parses request (parsed JSON object) and prepares JsonRpcRequest object.
6162 * @param $request
6263 * @return JsonRpcRequest
63- * @throws Exception
64+ * @throws JsonRpcException
6465 * @throws \yii\base\InvalidConfigException
6566 */
6667 public function parseRequest ($ request ) {
6768 if (!isset ($ request ->jsonrpc ) || $ request ->jsonrpc !== '2.0 ' ) {
68- throw new Exception ("The JSON sent is not a correct JSON-RPC request - missing or incorrect version. " , JSON_RPC_ERROR_REQUEST_INVALID );
69+ throw new JsonRpcException ("The JSON sent is not a correct JSON-RPC request - missing or incorrect version. " , JSON_RPC_ERROR_REQUEST_INVALID );
6970 }
7071
7172 if (!isset ($ request ->method ) || !is_string ($ request ->method ) || (!$ route = $ this ->parseMethod ($ request ->method ))) {
72- throw new Exception ("The JSON sent is not a correct JSON-RPC request - missing or incorrect method. " , JSON_RPC_ERROR_REQUEST_INVALID );
73+ throw new JsonRpcException ("The JSON sent is not a correct JSON-RPC request - missing or incorrect method. " , JSON_RPC_ERROR_REQUEST_INVALID );
7374 }
7475
7576 $ params = null ;
@@ -79,7 +80,7 @@ public function parseRequest($request) {
7980
8081 if (!isset ($ request ->id )) {
8182 if (!is_int ($ request ->id ) && !ctype_digit ($ request ->id )) {
82- throw new Exception ("The JSON sent is not a correct JSON-RPC request - incorrect id. " , JSON_RPC_ERROR_INVALID_REQUEST );
83+ throw new JsonRpcException ("The JSON sent is not a correct JSON-RPC request - incorrect id. " , JSON_RPC_ERROR_REQUEST_INVALID );
8384 }
8485 }
8586
@@ -95,7 +96,7 @@ public function parseRequest($request) {
9596 * Parses JSON to an array of JsonRpcRequest.
9697 * @param $params
9798 * @return JsonRpcRequest[]
98- * @throws Exception
99+ * @throws JsonRpcException
99100 */
100101 public function parseRequests ($ params ) {
101102 if (is_object ($ params )) {
@@ -109,29 +110,22 @@ public function parseRequests($params) {
109110 $ result = $ this ->parseRequest ($ request );
110111 }
111112 catch (\Exception $ exception ) {
112- if ($ exception instanceof Exception) {
113- if (isset ($ request ->id ) && is_string ($ request ->id ) || is_int ($ request ->id )) {
114- $ exception ->id = $ request ->id ;
115- }
116- $ result = $ exception ;
117- }
118- else {
119- $ result = new Exception ("Error happened during request parsing. " , JSON_RPC_ERROR_INTERNAL );
120- $ result ->data ['exception ' ] = $ exception ->getMessage ();
121- }
113+ $ result = ($ exception instanceof JsonRpcException)
114+ ? $ exception
115+ : new JsonRpcException ("Error happened during request parsing. " , JSON_RPC_ERROR_INTERNAL , $ exception );
122116 }
123117 $ results [] = $ result ;
124118 }
125119 return $ results ;
126120 }
127121
128- throw new Exception ("The JSON sent is not a correct JSON-RPC request. " , JSON_RPC_ERROR_INVALID_REQUEST );
122+ throw new JsonRpcException ("The JSON sent is not a correct JSON-RPC request. " , JSON_RPC_ERROR_REQUEST_INVALID );
129123 }
130124
131125 /**
132126 * Executes JSON-RPC request by route.
133127 * @param JsonRpcRequest $request
134- * @return Exception |mixed
128+ * @return JsonRpcException |mixed
135129 */
136130 public function executeRequest ($ request ) {
137131 $ route = $ request ->route ;
@@ -143,16 +137,14 @@ public function executeRequest($request) {
143137 }
144138 catch (\Exception $ exception ) {
145139 if ($ exception instanceof InvalidRouteException) {
146- $ result = new Exception ('Method not found. ' , JSON_RPC_ERROR_METHOD_NOT_FOUND );
147- $ result ->data ['message ' ] = $ exception ->getMessage ();
140+ $ result = new JsonRpcException ('Method not found. ' , JSON_RPC_ERROR_METHOD_NOT_FOUND , $ exception );
148141 return $ result ;
149142 }
150- else if ($ exception instanceof Exception ) {
143+ else if ($ exception instanceof JsonRpcException ) {
151144 return $ exception ;
152145 }
153146 else {
154- $ result = new Exception ('Internal error. ' , JSON_RPC_ERROR_INTERNAL );
155- $ result ->data ['message ' ] = $ exception ->getMessage ();
147+ $ result = new JsonRpcException ('Internal error. ' , JSON_RPC_ERROR_INTERNAL , $ exception );
156148 return $ result ;
157149 }
158150 }
@@ -167,31 +159,73 @@ public function runWithParams($params)
167159
168160 $ response = [];
169161 foreach ($ requestObjects as $ request ) {
170- if ($ request instanceof Exception) {
171- $ response [] = [
172- 'jsonrpc ' => '2.0 ' ,
173- 'error ' => $ request ->toJsonRpcFormat (),
174- 'id ' => $ request ->id
162+ $ executionResult = $ this ->executeRequest ($ request );
163+ $ renderMethod = ($ executionResult instanceof \Exception) ? 'renderError ' : 'renderSuccess ' ;
164+ $ response [] = $ this ->$ renderMethod ($ executionResult , $ request ->id );
165+ }
166+
167+ return (sizeof ($ response ) == 1 ) ? array_shift ($ response ) : $ response ;
168+ }
169+
170+ /**
171+ * Renders exception.
172+ * @param \Exception $exception
173+ * @return array
174+ */
175+ protected function renderException ($ exception ) {
176+ $ result = [
177+ 'code ' => $ exception ->getCode (),
178+ 'message ' => $ exception ->getMessage (),
179+ ];
180+
181+ if (YII_DEBUG ) {
182+ $ result ['data ' ] = [
183+ 'type ' => get_class ($ exception )
184+ ];
185+ if (!$ exception instanceof UserException) {
186+ $ result ['data ' ] += [
187+ 'file ' => $ exception ->getFile (),
188+ 'line ' => $ exception ->getLine (),
189+ 'stack-trace ' => explode ("\n" , $ exception ->getTraceAsString ())
175190 ];
176- }
177- else {
178- $ executionResult = $ this ->executeRequest ($ request );
179- if ($ executionResult instanceof Exception) {
180- $ response [] = [
181- 'jsonrpc ' => '2.0 ' ,
182- 'error ' => $ executionResult ->toJsonRpcFormat (),
183- 'id ' => $ request ->id
184- ];
185- } else {
186- $ response [] = [
187- 'jsonrpc ' => '2.0 ' ,
188- 'result ' => $ executionResult ,
189- 'id ' => $ request ->id
190- ];
191+
192+ if ($ exception instanceof \yii \db \Exception) {
193+ $ result ['data ' ]['error-info ' ] = $ exception ->errorInfo ;
191194 }
192195 }
193196 }
197+ if (($ prev = $ exception ->getPrevious ()) !== null ) {
198+ $ result ['data ' ]['previous ' ] = $ this ->renderException ($ prev );
199+ }
194200
195- return (sizeof ($ response ) == 1 ) ? array_shift ($ response ) : $ response ;
201+ return $ result ;
202+ }
203+
204+ /**
205+ * Renders error response.
206+ * @param $data
207+ * @param null $id
208+ * @return array
209+ */
210+ protected function renderError ($ data , $ id = null ) {
211+ return [
212+ 'jsonrpc ' => '2.0 ' ,
213+ 'error ' => ($ data instanceof \Exception) ? $ this ->renderException ($ data ) : $ data ,
214+ 'id ' => $ id ,
215+ ];
216+ }
217+
218+ /**
219+ * Renders success response.
220+ * @param $data
221+ * @param null $id
222+ * @return array
223+ */
224+ protected function renderSuccess ($ data , $ id = null ) {
225+ return [
226+ 'jsonrpc ' => '2.0 ' ,
227+ 'result ' => $ data ,
228+ 'id ' => $ id
229+ ];
196230 }
197231}
0 commit comments