Мне нужно подключиться к API, поэтому я пишу функцию:
try {
$res4 = $client3->post('https://api.example.co.uk/Book', [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ajhsdbjhasdbasdbasd',
],
'json' => [
'custFirstName' => $FirstName,
'custLastName' => $Surname,
'custPhone' => $Mobile,
'custEmail' => $Email,
]
]);
} catch (GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
$result = json_decode($response->getBody()->getContents());
$item->update(['status' => 'Problems at step3']);
Mail::raw('Problem at STEP 3', function ($message) use ($serial) {
$message->from('[email protected]', '[email protected]');
$message->subject('We got a problem etc.');
$message->to('[email protected]');
});
}
Как видите, мне нужно вызвать API, но в случае, когда API не работает, я пишу функции перехвата.
Но теперь, когда API не работает и API возвращает «500 Internal Error», эта функция просто вылетает ...
Мой вопрос в том, почему улов не справляется с этим?
Как я могу обрабатывать ошибки - когда API не работает или неверный запрос ... ПОЧЕМУ catch {} не работает?
ОБНОВЛЕНИЕ: вот мой laravel.log
[2018-10-25 14:51:04] local.ERROR: GuzzleHttp\Exception\ServerException: Server error: `POST https://api.example.co.uk/Book` resulted in a `500 Internal Server Error` response:
{"message":"An error has occured. Please contact support."}
in /home/public_html/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:107
Stack trace:
#0 /home/public_html/vendor/guzzlehttp/guzzle/src/Middleware.php(65): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))
#1 /home/public_html/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))
Возможно, это не ClientException
, вместо этого он перехватит корневое исключение Exception
.
Проверьте свой журнал и опубликуйте здесь полную ошибку.
Внутренняя ошибка 500 не является исключением, кстати.
из API я получил ошибку: ServerException в RequestException.php строка 107: Ошибка сервера: POST https://api.exampe.co.uk/Book
привел к ответу 500 Internal Server Error
: {"message": "Произошла ошибка. Обратитесь в службу поддержки."}
Обновляю вопрос. Пожалуйста, взгляните!
это ваш собственный или чужой API?
чужой API
@AleksPer хорошо, но я говорю в целом, вы не найдете исключения, которое было бы сгенерировано в случае внутренней ошибки сервера 500. Кроме того, причина, по которой он не был пойман, заключается в том, что вам нужно поймать суперкласс Exception
или, по крайней мере, ServerException
.
Хм. 4xx
- это ошибка пользователя, т.е. 400 вы отправили им хрень. 5xx
- это ошибка их
Если ответ об ошибке сервера можно поймать с помощью catch (Guzzle\Http\Exception\ServerErrorResponseException $e) { ... }
Как я могу справиться с любой полученной ошибкой?
просто catch (Exception $e){var_dump($e); exit;}
, который перехватит любое исключение. Если это не поможет, напишите им и отправьте им запрос
Я пытаюсь использовать только catch (Exception $ e), но снова получаю ошибку. Мне нужно просто отправить сообщение ALERT, если есть ошибка, и продолжить работу ... Мне не нужно сбой функции!
@AleksPer, что такое $client3
?
@AleksPer Я только что понял, почему catch
не работает в вашем случае, потому что это исключение было сгенерировано на их сервере, поэтому вы не можете его поймать на своей стороне.
но все, что я хочу, это если есть какая-то ошибка, чтобы не сбой функции, потому что это один из многих шагов там
@AleksPer, если вы говорите со мной, вам нужно будет упомянуть мое имя, иначе я не получу уведомления. Какой у вас код ответа HTTP? Наверное, с этим можно попробовать.
Проблема здесь в пространствах имен, а не в:
} catch (GuzzleHttp\Exception\ClientException $e) {
вам лучше использовать:
} catch (\GuzzleHttp\Exception\ClientException $e) {
В противном случае PHP предполагает, что класс находится в текущем пространстве имен, поэтому на самом деле, когда вы использовали GuzzleHttp\Exception\ClientException
, вы, вероятно, использовали App\Http\Controllers\GuzzleHttp\Exception\ClientException
, и такое исключение, очевидно, не будет создано Guzzle.
нет, это не решение, потому что я снова получил ту же ошибку. Все, что я хочу, это поймать ошибку API и обновить $ item, а также отправить сообщение ALERT на какой-то адрес электронной почты.
@AleksPer Хорошо, значит, в журнале ошибок у вас есть GuzzleHttp\Exception\ServerException
, так что вы можете заменить его на этот. Однако, поскольку у вас могут быть разные исключения, лучше заменить на } catch (\Exception $e) {
, чтобы действительно поймать любое исключение, которое может здесь произойти.
catch (\ Exception $ e) {обнаружит любую ошибку API? Я пробовал и кажется, что пока работает хорошо
@AleksPer Да, он должен перехватывать все возникающие исключения. Но если вы используете PHP 7, на всякий случай лучше использовать \Throwable
- см. php.net/manual/en/class.throwable.php
Это сработало для меня с исключением сторонней библиотеки.
Возникающее исключение - это экземпляр ServerException, а блок catch пытается перехватить ClientException.
} catch (GuzzleHttp\Exception\ServerException $e) {
in your app/exceptions/handler.php file, update the render method like this one.
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception) {
if ($exception instanceof \GuzzleHttp\Exception\ClientException) {
return your_response();
}
return parent::render($request, $exception);
}
This approach worked for me.
Пожалуйста, проверьте журнал laravel в папке /storage/log/laravel.log