使用curl发生API错误时如何读取响应体?
How to read the response body when API error happen using curl?
我使用 Slim v3
开发了一个 API
,当出现异常时,我有一个 ErrorHandler
,其中 return 以下内容:
public function __invoke(Request $request, Response $response, \Exception $exception)
{
$status = $exception->getCode() ? : 500;
$error = [
"status" => ERROR_MSG,
"data" => [
"stack_trace" => ($this->_container['settings']['displayErrorDetails']) ? $exception->getTraceAsString() : '',
],
"message" => $exception->getMessage()
];
$body = json_encode($error, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
return $response
->withStatus($status)
->withHeader("Content-type", "application/json")
->write($body);
}
所以基本上当 API
中发生异常时,例如:
throw new Exception('Invalid user credentials');
API
将 return 此响应:
{
"status": "error",
"data": {
"stack_trace": "some stack trace.."
},
"message": "Invalid user credentials"
}
现在的问题是,当我使用 curl
启动请求时,我只得到:
string(59) "The requested URL returned error: 500 Internal Server Error"
来自以下代码:
curl_error($this->session);
其中 $this->session
包含请求。
我还尝试使用以下方法调试请求:
$this->response = curl_exec($this->session);
$this->info = curl_getinfo($this->session);
$errno = curl_errno($this->session);
$error = curl_error($this->session);
我得到:
bool(false)
array(26) {
["url"]=>
string(48) "http://localhost/ci3-api/v1/installation/install"
["content_type"]=>
NULL
["http_code"]=>
int(500)
["header_size"]=>
int(0)
["request_size"]=>
int(148)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(0.25)
["namelookup_time"]=>
float(0.016)
["connect_time"]=>
float(0.219)
["pretransfer_time"]=>
float(0.219)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(-1)
["upload_content_length"]=>
float(0)
["starttransfer_time"]=>
float(0.25)
["redirect_time"]=>
float(0)
["redirect_url"]=>
string(0) ""
["primary_ip"]=>
string(9) "127.0.0.1"
["certinfo"]=>
array(0) {
}
["primary_port"]=>
int(80)
["local_ip"]=>
string(9) "127.0.0.1"
["local_port"]=>
int(65036)
}
int(22)
string(59) "The requested URL returned error: 500 Internal Server Error"
如何阅读 API
响应消息?
当 API
引发错误 500
时,似乎不可能这样做。
我尝试使用其他错误代码,例如 400
,我可以读取响应,但是对于错误代码 500
,我总是得到响应 false
.
这是我的设置;我认为对你来说重要的是 CURLOPT_RETURNTRANSFER 并且主要是 CURLOPT_FAILONERROR
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'your api url');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, false); // this is important for you I think
// other stuff you need to set
$output = curl_exec($ch);
$curlError = curl_error($ch);
$curlErrNo = curl_errno($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($output === false) {
// if header CURLOPT_FAILONERROR is true, always throw here
throw new RuntimeException('curl fail');
}
curl_close($ch);
// here process your output
关键是将CURLOPT_FAILONERROR
设置为false。当 third-party Web 服务的 http 响应代码 >= 400 时,我在获取响应正文时遇到了同样的问题,这解决了问题。
curl_setopt($ch, CURLOPT_FAILONERROR, false);
我使用 Slim v3
开发了一个 API
,当出现异常时,我有一个 ErrorHandler
,其中 return 以下内容:
public function __invoke(Request $request, Response $response, \Exception $exception)
{
$status = $exception->getCode() ? : 500;
$error = [
"status" => ERROR_MSG,
"data" => [
"stack_trace" => ($this->_container['settings']['displayErrorDetails']) ? $exception->getTraceAsString() : '',
],
"message" => $exception->getMessage()
];
$body = json_encode($error, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
return $response
->withStatus($status)
->withHeader("Content-type", "application/json")
->write($body);
}
所以基本上当 API
中发生异常时,例如:
throw new Exception('Invalid user credentials');
API
将 return 此响应:
{
"status": "error",
"data": {
"stack_trace": "some stack trace.."
},
"message": "Invalid user credentials"
}
现在的问题是,当我使用 curl
启动请求时,我只得到:
string(59) "The requested URL returned error: 500 Internal Server Error"
来自以下代码:
curl_error($this->session);
其中 $this->session
包含请求。
我还尝试使用以下方法调试请求:
$this->response = curl_exec($this->session);
$this->info = curl_getinfo($this->session);
$errno = curl_errno($this->session);
$error = curl_error($this->session);
我得到:
bool(false)
array(26) {
["url"]=>
string(48) "http://localhost/ci3-api/v1/installation/install"
["content_type"]=>
NULL
["http_code"]=>
int(500)
["header_size"]=>
int(0)
["request_size"]=>
int(148)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(0.25)
["namelookup_time"]=>
float(0.016)
["connect_time"]=>
float(0.219)
["pretransfer_time"]=>
float(0.219)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(-1)
["upload_content_length"]=>
float(0)
["starttransfer_time"]=>
float(0.25)
["redirect_time"]=>
float(0)
["redirect_url"]=>
string(0) ""
["primary_ip"]=>
string(9) "127.0.0.1"
["certinfo"]=>
array(0) {
}
["primary_port"]=>
int(80)
["local_ip"]=>
string(9) "127.0.0.1"
["local_port"]=>
int(65036)
}
int(22)
string(59) "The requested URL returned error: 500 Internal Server Error"
如何阅读 API
响应消息?
当 API
引发错误 500
时,似乎不可能这样做。
我尝试使用其他错误代码,例如 400
,我可以读取响应,但是对于错误代码 500
,我总是得到响应 false
.
这是我的设置;我认为对你来说重要的是 CURLOPT_RETURNTRANSFER 并且主要是 CURLOPT_FAILONERROR
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'your api url');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, false); // this is important for you I think
// other stuff you need to set
$output = curl_exec($ch);
$curlError = curl_error($ch);
$curlErrNo = curl_errno($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($output === false) {
// if header CURLOPT_FAILONERROR is true, always throw here
throw new RuntimeException('curl fail');
}
curl_close($ch);
// here process your output
关键是将CURLOPT_FAILONERROR
设置为false。当 third-party Web 服务的 http 响应代码 >= 400 时,我在获取响应正文时遇到了同样的问题,这解决了问题。
curl_setopt($ch, CURLOPT_FAILONERROR, false);