.. _root_error_handling:

Обработка ошибок
==========================================

``Argenta`` выбрасывает исключения в пограничных случаях, связанных с пользовательским вводом.
По умолчанию они обрабатываются системными обработчиками, но вы можете их переопределить. Это делается с помощью сеттеров экземпляра ``App`` вида ``.set_*_handler()``. Подробнее о каждом из них рассказано :ref:`ниже <possible_errors>`.

.. note::
    Ни одно исключение не остаётся необработанным, так как для каждого случая предусмотрен стандартный обработчик. Поэтому переопределение является опциональным.

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet.py
    :language: python
    :linenos:


.. _possible_errors:

Возможные исключения и нестандартное поведение
----------------------------------------------

``UnprocessedInputFlagException``: Некорректный синтаксис флагов
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Это исключение выбрасывается, когда парсер не может обработать команду из-за некорректного синтаксиса. Чаще всего это связано с ошибкой в синтаксисе флагов. Подробнее о них можно прочитать в разделе :ref:`Flags <root_flags>`.

Стандартный обработчик выводит в консоль:

.. code-block::  shell

    Incorrect flag syntax: <raw input command>

Для переопределения используется сеттер ``.set_incorrect_input_syntax_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[str], None]``, где единственный аргумент — это строка с необработанной командой.

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet2.py
   :language: python
   :linenos:

---------------

``RepeatedInputFlagsException``: Повторяющиеся флаги в команде
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Исключение выбрасывается, если пользователь ввёл команду с повторяющимися флагами. Два флага (:ref:`InputFlag <root_api_command_input_flag>`) считаются одинаковыми, если у них совпадают имена. Подробнее о флагах и их синтаксисе — в разделе :ref:`Flags <root_flags>`.

.. note::
    Сравнение на равенство у регистрируемых флагов (``Flag``) происходит иначе, подробнее в :ref:`Flag <root_flags>`.

Стандартный обработчик выводит в консоль:

.. code-block::  shell

    Repeated input flags: <raw input command>

Для переопределения используется сеттер ``.set_repeated_input_flags_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[str], None]``, где единственный аргумент — это строка с необработанной командой.

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet3.py
   :language: python
   :linenos:

---------------

``EmptyInputCommandException``: Введена пустая команда
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Исключение выбрасывается, если пользователь ввёл пустую строку или строку, состоящую только из пробельных символов (``\n``, ``\t``, пробел и т.д.).

Стандартный обработчик выводит в консоль:

.. code-block::  shell

    Empty input command

Для переопределения используется сеттер ``.set_empty_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[], None]`` (без аргументов).

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet4.py
    :language: python
    :linenos:

---------------

.. _root_error_handling_unknown_command:

Обработка неизвестной команды
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Это поведение активируется, когда пользователь вводит команду, которая не зарегистрирована ни в одном из роутеров и не является псевдонимом (alias) для существующей команды.

Стандартный обработчик выводит в консоль:

.. code-block::  shell

    Unknown command: <trigger of the input command>

Для переопределения используется сеттер ``.set_unknown_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[InputCommand], None]``, где аргумент — объект :ref:`InputCommand <root_api_command_input_command>`.

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet5.py
    :language: python
    :linenos:

---------------

Выход из приложения
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Стандартный обработчик выводит в консоль текст и завершает работу приложения:

.. code-block::  shell

    See you

Для переопределения используется сеттер ``.set_exit_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[Response], None]``, где аргумент — объект :ref:`Response <root_api_response>`.

**Пример использования:**

.. literalinclude:: ../code_snippets/error_handling/snippet6.py
    :language: python
    :linenos:
