Advertisement
  1. Code
  2. Laravel

Обработка исключений в Laravel

Scroll to top
Read Time: 7 min

() translation by (you can also view the original English article)

В этой статье мы рассмотрим одну из наиболее важных и наименее обсуждаемых функций Laravel web framework - обработку исключений. Laravel поставляется со встроенным обработчиком исключений, который позволяет легко и дружелюбно сообщать об исключениях.

В первой половине статьи мы рассмотрим настройки по умолчанию, предоставляемые обработчиком исключений. Фактически, мы рассмотрим класс Handler, чтобы понять, как Laravel обрабатывает исключения.

Во второй половине статьи мы поговорим о том, как создать пользовательский обработчик исключений, позволяющий обнаруживать пользовательские исключения.

Предварительная настройка

Прежде чем двигаться дальше и сразу погрузиться в класс Handler, давайте посмотрим на пару важных параметров конфигурации, связанных с исключениями.

Откройте файл config/app.php. Давайте внимательно рассмотрим следующий фрагмент.

1
...
2
...
3
/*

4
|--------------------------------------------------------------------------

5
| Application Debug Mode

6
|--------------------------------------------------------------------------

7
|

8
| When your application is in debug mode, detailed error messages with

9
| stack traces will be shown on every error that occurs within your

10
| application. If disabled, a simple generic error page is shown.

11
|

12
*/
13
14
'debug' => env('APP_DEBUG', false),
15
...
16
...

Как следует из названия, если оно установлено в TRUE, это поможет вам отлаживать ошибки, которые генерируются приложением. Значению по умолчанию этой переменной присваивается значение переменной среды APP_DEBUG в файле .env.

В среде разработки вы должны установить значение TRUE, чтобы вы могли легко отслеживать ошибки и исправлять их. С другой стороны, вы хотите отключить это в рабочей среде, и в этом случае будет отображаться общая страница ошибок.

В дополнение к отображению ошибок, Laravel позволяет регистрировать ошибки в файле журнала. Давайте быстро рассмотрим варианты, доступные для ведения журнала. Опять же, перейдем к файлу config/app.php и внимательно рассмотрим следующий фрагмент.

1
...
2
...
3
'log' => env('APP_LOG', 'single'),
4
5
'log_level' => env('APP_LOG_LEVEL', 'debug'),
6
...
7
...

Поскольку Laravel использует библиотеку Monolog PHP для ведения журнала, вы должны установить вышеуказанные параметры в контексте этой библиотеки.

Файл журнала по умолчанию находится в файле storage/logs/laravel.log, и в большинстве случаев этого достаточно. С другой стороны, APP_LOG_LEVEL устанавливается в значение, которое указывает на серьезность ошибок, которые будут регистрироваться.

Таким образом, это было базовое введение в параметры конфигурации, доступные для исключений и ведения логов.

Затем давайте взглянем на класс Handler, который поставляется с приложением Laravel по умолчанию. Откройте файл app/Exceptions/Handler.php.

1
<?php
2
3
namespace App\Exceptions;
4
5
use Exception;
6
use Illuminate\Auth\AuthenticationException;
7
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
8
9
class Handler extends ExceptionHandler
10
{
11
    /**

12
     * A list of the exception types that should not be reported.

13
     *

14
     * @var array

15
     */
16
    protected $dontReport = [
17
        \Illuminate\Auth\AuthenticationException::class,
18
        \Illuminate\Auth\Access\AuthorizationException::class,
19
        \Symfony\Component\HttpKernel\Exception\HttpException::class,
20
        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
21
        \Illuminate\Session\TokenMismatchException::class,
22
        \Illuminate\Validation\ValidationException::class,
23
    ];
24
25
    /**

26
     * Report or log an exception.

27
     *

28
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.

29
     *

30
     * @param  \Exception  $exception

31
     * @return void

32
     */
33
    public function report(Exception $exception)
34
    {
35
        parent::report($exception);
36
    }
37
38
    /**

39
     * Render an exception into an HTTP response.

40
     *

41
     * @param  \Illuminate\Http\Request  $request

42
     * @param  \Exception  $exception

43
     * @return \Illuminate\Http\Response

44
     */
45
    public function render($request, Exception $exception)
46
    {
47
        return parent::render($request, $exception);
48
    }
49
50
    /**

51
     * Convert an authentication exception into an unauthenticated response.

52
     *

53
     * @param  \Illuminate\Http\Request  $request

54
     * @param  \Illuminate\Auth\AuthenticationException  $exception

55
     * @return \Illuminate\Http\Response

56
     */
57
    protected function unauthenticated($request, AuthenticationException $exception)
58
    {
59
        if ($request->expectsJson()) {
60
            return response()->json(['error' => 'Unauthenticated.'], 401);
61
        }
62
63
        return redirect()->guest(route('login'));
64
    }
65
}

Существуют две важные функции, за которые отвечает класс Handler: сообщение и визуализация всех ошибок.

Давайте внимательно рассмотрим метод report.

1
/**

2
 * Report or log an exception.

3
 *

4
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.

5
 *

6
 * @param  \Exception  $exception

7
 * @return void

8
 */
9
public function report(Exception $exception)
10
{
11
    parent::report($exception);
12
}

Метод report используется для регистрации ошибок в файле логов. В то же время важно также отметить свойство dontReport, в котором перечислены все типы исключений, которые не должны регистрироваться.

Затем давайте изучим метод render.

1
/**

2
 * Render an exception into an HTTP response.

3
 *

4
 * @param  \Illuminate\Http\Request  $request

5
 * @param  \Exception  $exception

6
 * @return \Illuminate\Http\Response

7
 */
8
public function render($request, Exception $exception)
9
{
10
    return parent::render($request, $exception);
11
}

Если метод report используется для регистрации или сообщения об ошибках, метод render используется для визуализации ошибок на экране. Фактически, этот метод обрабатывает то, что будет отображаться пользователям при возникновении исключения.

Метод render также позволяет настраивать ответ для разных типов исключений, как мы увидим в следующем разделе.

Наконец, метод unauthenticated обрабатывает исключение AuthenticationException, которое позволяет вам определять, что будет отображаться для пользователей, если они не прошли проверку подлинности для доступа к странице, которую они ищут.

Пользовательский класс исключения

В этом разделе мы создадим собственный класс исключений, который обрабатывает исключения типа CustomException. Идея создания пользовательских классов исключений заключается в том, чтобы легко управлять пользовательскими исключениями и одновременно создавать настраиваемые ответы.

Двигаемся дальше и создаем файл app/Exceptions/CustomException.php со следующим содержимым.

1
<?php
2
3
namespace App\Exceptions;
4
5
use Exception;
6
7
class CustomException extends Exception
8
{
9
    /**

10
     * Report the exception.

11
     *

12
     * @return void

13
     */
14
    public function report()
15
    {
16
    }
17
18
    /**

19
     * Render the exception into an HTTP response.

20
     *

21
     * @param  \Illuminate\Http\Request

22
     * @return \Illuminate\Http\Response

23
     */
24
    public function render($request)
25
    {
26
        return response()->view(
27
                'errors.custom',
28
                array(
29
                    'exception' => $this
30
                )
31
        );
32
    }
33
}

Важно отметить, что класс CustomException должен расширять основной класс Exception. Для демонстрационных целей мы обсудим только метод render, но, конечно, вы также можете настроить метод report.

Как вы можете видеть, в нашем случае мы перенаправляем пользователей на страницу ошибок error.custom. Таким образом, вы можете создавать собственные страницы ошибок для определенных типов исключений.

Конечно, нам нужно создать соответствующий файл представления в resources/views/errors/custom.blade.php.

1
Exception details: <b>{{ $exception->getMessage() }}</b>

Это довольно простой файл, который отображает сообщение об ошибке, но, конечно же, вы могли бы спроектировать его так, как вы этого хотите.

Нам также необходимо внести изменения в метод render файла app/Exceptions/Handler.php, чтобы наш пользовательский класс исключений мог быть вызван. Давайте заменим метод render следующим содержимым в файле app/Exceptions/Handler.php.

1
...
2
...
3
/**

4
 * Render an exception into an HTTP response.

5
 *

6
 * @param  \Illuminate\Http\Request  $request

7
 * @param  \Exception  $exception

8
 * @return \Illuminate\Http\Response

9
 */
10
public function render($request, Exception $exception)
11
{
12
    if ($exception instanceof \App\Exceptions\CustomException)  {
13
        return $exception->render($request);
14
    }
15
16
    return parent::render($request, $exception);
17
}
18
...
19
...

Как вы можете видеть, сперва мы проверяем тип исключения в методе render. Если тип исключения - \App\Exceptions\CustomException, мы вызываем метод render этого класса.

Итак, все уже готово. Далее, давайте продолжим и создадим файл контроллера в app/Http/Controllers/ExceptionController.php, чтобы мы могли протестировать наш собственный класс исключений.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
6
class ExceptionController extends Controller
7
{
8
    public function index()
9
    {
10
        // something went wrong and you want to throw CustomException

11
        throw new \App\Exceptions\CustomException('Something Went Wrong.');
12
    }
13
}

Конечно, вам нужно добавить соответствующий маршрут в routes/web.php, как показано в следующем фрагменте.

1
// Exception routes

2
Route::get('exception/index', 'ExceptionController@index');

И теперь вы можете открыть http://your-laravel-site.com/exception/index , чтобы узнать, работает ли он так, как ожидалось. Он должен отображать представление errors.custom в соответствии с нашей конфигурацией.

Таким образом, вы должны обрабатывать пользовательские исключения в Laravel. На этом мы подходим к концу этой статьи - надеюсь, вам понравилось!

Вывод

Сегодня мы изучили функцию обработки исключений в Laravel. В начале статьи мы рассмотрели базовую конфигурацию, предоставленную Laravel, чтобы отображать и сообщать об исключениях. Кроме того, мы кратко рассмотрели класс обработчика исключений по умолчанию.

Во второй половине статьи мы подготовили специальный класс обработчика исключений, который продемонстрировал, как вы можете обрабатывать пользовательские исключения в своем приложении.

Для тех из вас, кто только начинает работать с Laravel или хочет расширить свои знания, сайт или приложение с расширениями, у нас есть множество вещей, которые вы можете изучать на Envato Market.

Оставляйте свои идеи и вопросы ниже в комментариях!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.