Skip to content

Commit b5cb482

Browse files
authored
Merge pull request #190 from juvenn/fix/exception
梳理错误处理
2 parents 1d8a592 + 668ad59 commit b5cb482

File tree

8 files changed

+112
-47
lines changed

8 files changed

+112
-47
lines changed

src/LeanCloud/Client.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,13 +435,15 @@ public static function request($method, $path, $data,
435435
$errno);
436436
}
437437
if (strpos($respType, "text/html") !== false) {
438-
throw new CloudException("Bad request", -1);
438+
throw new CloudException("Bad response type text/html", -1, $respCode,
439+
$method, $url);
439440
}
440441

441442
$data = json_decode($resp, true);
442443
if (isset($data["error"])) {
443444
$code = isset($data["code"]) ? $data["code"] : -1;
444-
throw new CloudException("{$code} {$data['error']}", $code);
445+
throw new CloudException("{$data['error']}", $code, $respCode,
446+
$method, $url);
445447
}
446448
return $data;
447449
}

src/LeanCloud/CloudException.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,39 @@
55
* Exception thrown when cloud API returns error
66
*/
77
class CloudException extends \Exception {
8-
public function __construct($message, $code = 1) {
8+
9+
/**
10+
* Http status returned by API
11+
*
12+
* @var int
13+
*/
14+
public $status;
15+
16+
/**
17+
* Http method request to API
18+
*
19+
* @var string
20+
*/
21+
public $method;
22+
23+
/**
24+
* Http url request to API
25+
*
26+
* @var string
27+
*/
28+
public $url;
29+
30+
public function __construct($message, $code = 1, $status = 400,
31+
$method=null, $url=null) {
932
parent::__construct($message, $code);
33+
$this->status = $status;
34+
$this->method = $method;
35+
$this->url = $url;
1036
}
1137

1238
public function __toString() {
13-
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
39+
$req = $this->method ? ": {$this->method} {$this->url}": "";
40+
return __CLASS__ . ": [{$this->code}] {$this->message}{$req}\n";
1441
}
1542
}
1643

src/LeanCloud/Engine/FunctionError.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55
* Error thrown when invoking function error
66
*/
77
class FunctionError extends \Exception {
8-
public function __construct($message, $code = 1) {
8+
9+
/**
10+
* Http status code
11+
*/
12+
public $status;
13+
14+
public function __construct($message, $code = 1, $status = 400) {
915
parent::__construct($message, $code);
16+
$this->status = $status;
1017
}
1118

1219
public function __toString() {
13-
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
20+
return __CLASS__ . ": [{$this->code}] {$this->message}\n";
1421
}
1522
}

src/LeanCloud/Engine/LeanEngine.php

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ private function processSession() {
335335
* @param string $method Request method
336336
* @param string $url Request url
337337
*/
338-
protected function dispatch($method, $url) {
338+
private function __dispatch($method, $url) {
339339
if (static::$useHttpsRedirect) {
340340
$this->httpsRedirect();
341341
}
@@ -393,41 +393,26 @@ protected function dispatch($method, $url) {
393393
// extract func params from path:
394394
// /1.1/call/{0}/{1}
395395
$funcParams = explode("/", ltrim($pathParts["extra"], "/"));
396-
try {
397-
if (count($funcParams) == 1) {
398-
// {1,1.1}/functions/{funcName}
399-
$this->dispatchFunc($funcParams[0], $json,
400-
$pathParts["endpoint"] === "call");
401-
} else {
402-
if ($funcParams[0] == "onVerified") {
403-
// {1,1.1}/functions/onVerified/sms
404-
$this->dispatchOnVerified($funcParams[1], $json);
405-
} else if ($funcParams[0] == "_User" &&
406-
$funcParams[1] == "onLogin") {
407-
// {1,1.1}/functions/_User/onLogin
408-
$this->dispatchOnLogin($json);
409-
} else if ($funcParams[0] == "BigQuery" ||
410-
$funcParams[0] == "Insight") {
411-
// {1,1.1}/functions/Insight/onComplete
412-
$this->dispatchOnInsight($json);
413-
} else if (count($funcParams) == 2) {
414-
// {1,1.1}/functions/{className}/beforeSave
415-
$this->dispatchHook($funcParams[0], $funcParams[1], $json);
416-
}
396+
if (count($funcParams) == 1) {
397+
// {1,1.1}/functions/{funcName}
398+
$this->dispatchFunc($funcParams[0], $json,
399+
$pathParts["endpoint"] === "call");
400+
} else {
401+
if ($funcParams[0] == "onVerified") {
402+
// {1,1.1}/functions/onVerified/sms
403+
$this->dispatchOnVerified($funcParams[1], $json);
404+
} else if ($funcParams[0] == "_User" &&
405+
$funcParams[1] == "onLogin") {
406+
// {1,1.1}/functions/_User/onLogin
407+
$this->dispatchOnLogin($json);
408+
} else if ($funcParams[0] == "BigQuery" ||
409+
$funcParams[0] == "Insight") {
410+
// {1,1.1}/functions/Insight/onComplete
411+
$this->dispatchOnInsight($json);
412+
} else if (count($funcParams) == 2) {
413+
// {1,1.1}/functions/{className}/beforeSave
414+
$this->dispatchHook($funcParams[0], $funcParams[1], $json);
417415
}
418-
} catch (FunctionError $ex) {
419-
error_log($ex->getMessage());
420-
error_log($ex->getTraceAsString());
421-
$this->renderError("Cloud function error: {$ex->getMessage()}", $ex->getCode());
422-
} catch (CloudException $ex) {
423-
error_log($ex->getMessage());
424-
error_log($ex->getTraceAsString());
425-
$this->renderError("Request to API failed: {$ex->getMessage()}", $ex->getCode());
426-
} catch (\Exception $ex) {
427-
error_log($ex->getMessage());
428-
error_log($ex->getTraceAsString());
429-
$this->renderError($ex->getMessage(),
430-
$ex->getCode() ? $ex->getCode() : 1);
431416
}
432417
}
433418
}
@@ -576,6 +561,36 @@ private function dispatchOnInsight($body) {
576561
$this->renderJSON(array("result" => "ok"));
577562
}
578563

564+
/**
565+
* Dispatch LeanEngine functions.
566+
*
567+
* @param string $method Request method
568+
* @param string $url Request url
569+
*/
570+
protected function dispatch($method, $url) {
571+
try {
572+
$this->__dispatch($method, $url);
573+
} catch (FunctionError $ex) {
574+
$status = (int) $ex->status;
575+
if ( $status >= 500) {
576+
error_log($ex);
577+
error_log($ex->getTraceAsString());
578+
}
579+
$this->renderError("{$ex->getMessage()}", $ex->getCode(), $ex->status);
580+
} catch (CloudException $ex) {
581+
error_log($ex);
582+
error_log($ex->getTraceAsString());
583+
$this->renderError("{$ex->getMessage()}", $ex->getCode(), $ex->status);
584+
} catch (\Exception $ex) {
585+
error_log($ex);
586+
error_log($ex->getTraceAsString());
587+
$this->renderError($ex->getMessage(),
588+
$ex->getCode() ? $ex->getCode() : 1,
589+
// unhandled internal exception
590+
500);
591+
}
592+
}
593+
579594
/**
580595
* Start engine and process request
581596
*/

src/LeanCloud/Query.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -712,10 +712,7 @@ public function get($objectId) {
712712
*/
713713
public function first() {
714714
$objects = $this->find($this->skip, 1);
715-
if (empty($objects)) {
716-
throw new CloudException("Object not found.", 101);
717-
}
718-
return $objects[0];
715+
return empty($objects) ? null : $objects[0];
719716
}
720717

721718
/**

test/APITest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function testIncrementOnStringField() {
2222
$resp = Client::post("/classes/TestObject", $obj);
2323

2424
$this->setExpectedException("LeanCloud\CloudException",
25-
"111 Invalid value type for field", 111);
25+
"Invalid value type for field", 111);
2626
$resp2 = Client::put("/classes/TestObject/" . $resp["objectId"],
2727
array("name" => array("__op" => "Increment",
2828
"amount" => 1)));

test/engine/LeanEngineTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,16 @@ function($k, $v) {return "$k: $v";},
5050
}
5151
$resp = curl_exec($req);
5252
$errno = curl_errno($req);
53+
$respCode = curl_getinfo($req, CURLINFO_HTTP_CODE);
5354
curl_close($req);
5455
if ($errno > 0) {
5556
throw new \RuntimeException("CURL connection error $errno: $url");
5657
}
5758
$data = json_decode($resp, true);
5859
if (isset($data["error"])) {
5960
$code = isset($data["code"]) ? $data["code"] : -1;
60-
throw new CloudException("{$code} {$data['error']}", $code);
61+
throw new CloudException("{$data['error']}", $code, $respCode,
62+
$method, $url);
6163
}
6264
return $data;
6365
}
@@ -210,5 +212,15 @@ public function test_messageReceived() {
210212
$this->assertEquals(false, $resp["result"]["drop"]);
211213
}
212214

215+
public function testFunctionError() {
216+
try {
217+
$this->request("/1.1/functions/customError", "POST", array());
218+
} catch (CloudException $ex) {
219+
$this->assertEquals("My custom error.", $ex->getMessage());
220+
$this->assertEquals(1, $ex->getCode());
221+
$this->assertEquals(500, $ex->status);
222+
}
223+
}
224+
213225
}
214226

test/engine/index.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use LeanCloud\Client;
66
use LeanCloud\Engine\LeanEngine;
77
use LeanCloud\Engine\Cloud;
8+
use LeanCloud\Engine\FunctionError;
89
use LeanCloud\Storage\CookieStorage;
910

1011
Client::initialize(
@@ -25,6 +26,10 @@
2526
return "hello {$params['name']}";
2627
});
2728

29+
Cloud::define("customError", function($params, $user) {
30+
throw new FunctionError("My custom error.", 1, 500);
31+
});
32+
2833
Cloud::define("_messageReceived", function($params, $user){
2934
if ($params["convId"]) {
3035
return array("drop" => false);

0 commit comments

Comments
 (0)