Advertisement
  1. Code
  2. Laravel 5

Исключения в Laravel

Scroll to top
Read Time: 4 min

Russian (Pусский) translation by Sergey Zhuk (you can also view the original English article)

Будучи разработчиком PHP, вы скорее всего уже использовали исключения, потому что они позволяют вам заметить, когда что-то идет не так, или пользователь ведет себя некорректным образом (например делит на ноль). Без исключений ваше приложению завершилось бы показом нежелательных ошибок, которые было бы гораздо тяжелее отлаживать.  Так же важно, что можно сразу прекратить выполнение и перевести управление программы в другое направление.

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

Что такое исключение?

Я думаю, что лучшее определение исключениям дал Мартин Фаулер:

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

Действительно в самом деле, исключение является событием, которое происходит во время выполнения программы, когда нарушается нормальный поток инструкций. Когда вы выбрасываете (throw, создаете объект исключения и передаете его в среду выполнения), система поймает (catch) его с помощью соответствующего обработчика и вернет соответствующее сообщение.

1
try { 
2
    // the code goes here 

3
} catch (Exception $e) { 
4
    // if an exception happened in the try block above 

5
6
}

Когда нам следует использовать исключения?

Используйте исключения, когда ваша система сталкивается с исключительными ситуациями, которые могут привести к неправильной ее работе. Мы используем исключения только тогда, когда система не может определить, что произошло. Мартин Фаулер считает, что "если аварийное завершение программы - это ожидаемое поведение, то не стоит в таком случае использовать исключения". Это означает, что исключения следует использовать только тогда, когда вы не можете сами определить ошибку. Исключения должны быть использованы только в исключительных ситуациях.

Обратите внимание: исключения не очень подходят для взаимодействия с логическими операциями.

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

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

Что же представляют собой исключения в Laravel?

Laravel использует обработчик исключений, который находится в классе App\Exceptions\Handler.php. Этот класс содержит два основных метода (renderHttpException, который используется для всех HTTP исключений, как например 404 или 503, находится в родительском классе). Первый - это report, который логирует исключения или отправляет их во внешний сервис. Вот пример метода report:

1
2
public function report(Exception $e)
3
{
4
    if ($e instanceof CustomException) {
5
        //

6
    }
7
8
    return parent::report($e);
9
}

Второй - render. Метод render отвечает за преобразование переданного ему исключения в HTTP ответ, который будет отправлен назад браузеру. Вот пример метода render:

1
public function render($request, Exception $e)
2
{
3
    if ($e instanceof CustomException) {
4
        return response()->view('errors.custom', [], 500);
5
    }
6
7
    return parent::render($request, $e);
8
}

Обратите внимание: можно воспользоваться свойством $dontReport у обработчика, чтобы игнорировать некоторые типы исключений.

Вы можете переопределить исключения Laravel со своими собственными исключениями:

1
public function render($request, Exception $e)
2
{
3
    if (config('app.debug')) {
4
        return parent::render($request, $e);
5
    }
6
    return $this->handle($request, $e);
7
}

Это будет выведено, когда в конфиге установлен debug режим.

Как создать собственные исключения в Laravel?

Возможно вам потребовалось создать собственный класс с исключением. Нужно отнаследоваться от базового класса Exception в Larevel. Я создал абстрактный класс, который будет вести себя как базовый, для нашего пользовательского исключения.  Создадим файл в App/Exceptions/monException.php:

1
namespace App\Exceptions;
2
use Exception;
3
abstract class monException extends Exception
4
{
5
    protected $id;
6
    protected $details;
7
    
8
    public function __construct($message)
9
    {
10
        parent::__construct($message);
11
    }
12
13
    protected function create(array $args)
14
    {
15
        $this->id = array_shift($args);
16
        $error = $this->errors($this->id);
17
        $this->details = vsprintf($error['context'], $args);
18
        return $this->details;
19
    }
20
21
    private function errors($id)
22
    {
23
        $data= [
24
            'not_found' => [
25
                'context'  => 'The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.',
26
            ]
27
            //   ...

28
        ];
29
        return $data[$id];
30
    }
31
}

И ваш класс исключения:

1
namespace App\Exceptions;
2
class NotFoundmonException extends  monException
3
{
4
    public function __construct()
5
    {
6
        $message = $this->create(func_get_args());
7
        parent::__construct($message);
8
    }
9
}

Этот класс можно теперь использовать в коде:

1
    try {
2
        throw new \App\Exceptions\NotFoundmonException('not_found');
3
    }
4
    catch(\App\Exceptions\NotFoundmonException $e)
5
    {
6
        return $e->getMessage();
7
    }

Помимо основного класса исключений Laravel, можно использовать библиотеку Assertion. Она может использоваться в качестве стороннего класса исключений; можно воспользоваться ей, чтобы избежать множества if блоков в вашем коде.

Чтобы установить Assertion, следует выполнить следующую команду:

1
composer require beberlei/assert

Например если вам нужно проверить email пользователя, то можно выполнить следующее:

1
use Assert\Assertion;
2
use Assert\AssertionFailedException;
3
//...

4
try {
5
    Assertion::email($value, "The value must be valid E-mail address");
6
} catch(AssertionFailedException $e) {
7
    $e->getValue(); // the value that caused the failure

8
    $e->getConstraints(); // the additional constraints of the assertion.

9
}

Заключение

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

Кроме того они помогают нам логировать различные проблемы и помогают сделать наше приложение более надежным.

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

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.