Как отловить ошибку 500 в контроллере с помощью Laravel

Мне нужно подключиться к 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))

Пожалуйста, проверьте журнал laravel в папке /storage/log/laravel.log

Sergey B. 25.10.2018 16:46

Возможно, это не ClientException, вместо этого он перехватит корневое исключение Exception.

online Thomas 25.10.2018 16:46

Проверьте свой журнал и опубликуйте здесь полную ошибку.

Jerodev 25.10.2018 16:48

Внутренняя ошибка 500 не является исключением, кстати.

nice_dev 25.10.2018 16:49

из API я получил ошибку: ServerException в RequestException.php строка 107: Ошибка сервера: POST https://api.exampe.co.uk/Book привел к ответу 500 Internal Server Error: {"message": "Произошла ошибка. Обратитесь в службу поддержки."}

Aleks Per 25.10.2018 16:51

Обновляю вопрос. Пожалуйста, взгляните!

Aleks Per 25.10.2018 16:54

это ваш собственный или чужой API?

delboy1978uk 25.10.2018 16:54

чужой API

Aleks Per 25.10.2018 16:54

@AleksPer хорошо, но я говорю в целом, вы не найдете исключения, которое было бы сгенерировано в случае внутренней ошибки сервера 500. Кроме того, причина, по которой он не был пойман, заключается в том, что вам нужно поймать суперкласс Exception или, по крайней мере, ServerException.

nice_dev 25.10.2018 16:54

Хм. 4xx - это ошибка пользователя, т.е. 400 вы отправили им хрень. 5xx - это ошибка их

delboy1978uk 25.10.2018 16:55

Если ответ об ошибке сервера можно поймать с помощью catch (Guzzle\Http\Exception\ServerErrorResponseException $e) { ... }

Djamel Kr 25.10.2018 16:55

Как я могу справиться с любой полученной ошибкой?

Aleks Per 25.10.2018 16:55

просто catch (Exception $e){var_dump($e); exit;}, который перехватит любое исключение. Если это не поможет, напишите им и отправьте им запрос

delboy1978uk 25.10.2018 16:56

Я пытаюсь использовать только catch (Exception $ e), но снова получаю ошибку. Мне нужно просто отправить сообщение ALERT, если есть ошибка, и продолжить работу ... Мне не нужно сбой функции!

Aleks Per 25.10.2018 17:00

@AleksPer, что такое $client3?

nice_dev 25.10.2018 17:01

@AleksPer Я только что понял, почему catch не работает в вашем случае, потому что это исключение было сгенерировано на их сервере, поэтому вы не можете его поймать на своей стороне.

nice_dev 25.10.2018 17:02

но все, что я хочу, это если есть какая-то ошибка, чтобы не сбой функции, потому что это один из многих шагов там

Aleks Per 25.10.2018 17:05

@AleksPer, если вы говорите со мной, вам нужно будет упомянуть мое имя, иначе я не получу уведомления. Какой у вас код ответа HTTP? Наверное, с этим можно попробовать.

nice_dev 25.10.2018 17:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
18
6 712
3

Ответы 3

Проблема здесь в пространствах имен, а не в:

} catch (GuzzleHttp\Exception\ClientException $e) {

вам лучше использовать:

} catch (\GuzzleHttp\Exception\ClientException $e) {

В противном случае PHP предполагает, что класс находится в текущем пространстве имен, поэтому на самом деле, когда вы использовали GuzzleHttp\Exception\ClientException, вы, вероятно, использовали App\Http\Controllers\GuzzleHttp\Exception\ClientException, и такое исключение, очевидно, не будет создано Guzzle.

нет, это не решение, потому что я снова получил ту же ошибку. Все, что я хочу, это поймать ошибку API и обновить $ item, а также отправить сообщение ALERT на какой-то адрес электронной почты.

Aleks Per 25.10.2018 17:17

@AleksPer Хорошо, значит, в журнале ошибок у вас есть GuzzleHttp\Exception\ServerException, так что вы можете заменить его на этот. Однако, поскольку у вас могут быть разные исключения, лучше заменить на } catch (\Exception $e) {, чтобы действительно поймать любое исключение, которое может здесь произойти.

Marcin Nabiałek 25.10.2018 17:19

catch (\ Exception $ e) {обнаружит любую ошибку API? Я пробовал и кажется, что пока работает хорошо

Aleks Per 25.10.2018 17:36

@AleksPer Да, он должен перехватывать все возникающие исключения. Но если вы используете PHP 7, на всякий случай лучше использовать \Throwable - см. php.net/manual/en/class.throwable.php

Marcin Nabiałek 25.10.2018 17:56

Это сработало для меня с исключением сторонней библиотеки.

vrerabek 02.11.2020 12:01

Возникающее исключение - это экземпляр 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.

Другие вопросы по теме