Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Показ стека вызовов при ошибках в приложении #8

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
63 changes: 43 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# autumn-cli
# autumn-cli

Обертка над [cli](https://github.com/khorevaa/cli) библиотекой, которая предоставляет возможности создания консольных приложений на фреймворке [ОСень](https://github.com/autumn-library/autumn).

Comment on lines +1 to 4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [152-152]

В описании параметров аннотаций предложение начинается с маленькой буквы. Рекомендуется исправить для улучшения читаемости.

- параметр повторяемый, т.е. может быть несколько подкоманд.
+ Параметр повторяемый, т.е. может быть несколько подкоманд.

Expand Down Expand Up @@ -38,7 +38,7 @@

&КомандаПриложения(Имя = "p plus", Описание = "Прибавляет 10 к заданному числу") // Аннотация, обозначающая, что этот класс - консольная команда
Процедура ПриСозданииОбъекта()

КонецПроцедуры

&ВыполнениеКоманды // Метод, помеченный этой аннотацией будет выполнены при вызове команды.
Expand All @@ -47,15 +47,15 @@
Результат = ПереданноеЧисло + 10;

Сообщить("Результат сложения: " + Результат);

КонецПроцедуры
```

В этом примере мы определили класс как команду консольного приложения с помощью аннотации
В этом примере мы определили класс как команду консольного приложения с помощью аннотации

```&КомандаПриложения(Имя = "p plus", Описание = "Прибавляет 10 к заданному числу")```

В которой указали имя команды и ее описание. А для определения аргумента команды, была создана переменная с аннотацией
В которой указали имя команды и ее описание. А для определения аргумента команды, была создана переменная с аннотацией

```&Аргумент(Имя = "ARG", Описание = "Значение числа")```

Expand All @@ -74,7 +74,7 @@

&КомандаПриложения(Имя = "H hello", Описание = "Поздоровается с пользователем")
Процедура ПриСозданииОбъекта()

КонецПроцедуры

&ВыполнениеКоманды
Expand All @@ -83,11 +83,11 @@
ТекстСообщения = "Привет " + ИмяПользователя + "!";

Сообщить(ТекстСообщения);

КонецПроцедуры
```

В этом примере, для определения опции команды, была создана переменная с аннотацией
В этом примере, для определения опции команды, была создана переменная с аннотацией

```&Опция(Имя = "n name", Описание = "Имя пользователя")```

Expand All @@ -97,13 +97,13 @@

```Каталог/С/Классами/Команд/КомандаДата.os```
```bsl
&КомандаПриложения(Имя = "d date",
&КомандаПриложения(Имя = "d date",
Описание = "Выводит дату",
Подкоманда = "ПодкомандаДень",
Подкоманда = "ПодкомандаМесяц"
)
Процедура ПриСозданииОбъекта()

КонецПроцедуры
```

Expand All @@ -113,7 +113,7 @@
```bsl
&ПодкомандаПриложения(Имя = "day", Описание = "Выводит дату - начало дня")
Процедура ПриСозданииОбъекта()

КонецПроцедуры

&ВыполнениеКоманды
Expand All @@ -128,14 +128,14 @@
```bsl
&ПодкомандаПриложения(Имя = "month", Описание = "Выводит дату - начало месяца")
Процедура ПриСозданииОбъекта()

КонецПроцедуры

&ВыполнениеКоманды
Процедура СообщитьМесяц() Экспорт

Сообщить(НачалоМесяца(ТекущаяДата()));

КонецПроцедуры
```

Expand Down Expand Up @@ -192,7 +192,7 @@

Настройку вывода версии и имени приложения можно осуществить двумя способами.

1) Создать рядом с точкой входа файл
1) Создать рядом с точкой входа файл

```autumn-properties.json```
```json
Expand Down Expand Up @@ -227,11 +227,36 @@
КонецФункции
```

## Настройка показа полного стека вызовов при ошибках приложения

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

Чтобы исключить показ стека вызовов при ошибках, нужно

- в файле `autumn-properties.json` указать значение `false` для ключа `ПоказыватьСтекВызововПриОшибке` в корневом разделе `cli`
- пример файла
```json
{
"cli": {
"ИмяПриложения": "cli_test",
"ПолноеИмяПриложения": "cli_test v%{cli.ВерсияПриложения}",
"ВерсияПриложения": "1.0.1",
"ПоказыватьСтекВызововПриОшибке" : false
}
}
```

Чтобы включить показ стека вызовов при ошибках, можно
- или задать `true`
- или просто удалить ключ из файла для возврата поведения по умолчанию.


## Миграция с [cli](https://github.com/khorevaa/cli)

Инфраструктурный, условный ```main.os``` от вашего приложения не нужен. он должен быть запущен при помощи [ОСени](https://github.com/autumn-library/autumn). Дальше перед вами три пути:
Инфраструктурный, условный ```main.os``` от вашего приложения не нужен. он должен быть запущен при помощи [ОСени](https://github.com/autumn-library/autumn). Дальше перед вами три пути:

Первый - команды модифицировать аннотациями конструктора ```&КомандаПриложения``` или ```&ПодкомандаПриложения```. оставить методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, тогда фреймворк поймет что они уже реализованы, и не будет генерировать для них код.
Первый - команды модифицировать аннотациями конструктора ```&КомандаПриложения``` или ```&ПодкомандаПриложения```. оставить методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, тогда фреймворк поймет что они уже реализованы, и не будет генерировать для них код.

Второй - команды модифицировать аннотациями конструктора ```&КомандаПриложения``` или ```&ПодкомандаПриложения```. убрать методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, и создать поля класса, с необходимыми аннотациями, и метод с аннотацией ```&ВыполнениеКоманды```. В таком случае фреймворк сгенерит все остальное за вас.

Comment on lines 227 to 262
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [257-263]

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

- он должен быть запущен при помощи [ОСени](https://github.com/autumn-library/autumn).
+ Он должен быть запущен при помощи [ОСени](https://github.com/autumn-library/autumn).
- оставить методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, тогда фреймворк поймет что они уже реализованы, и не будет генерировать для них код.
+ Оставить методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, тогда фреймворк поймет что они уже реализованы, и не будет генерировать для них код.
- убрать методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, и создать поля класса, с необходимыми аннотациями, и метод с аннотацией ```&ВыполнениеКоманды```.
+ Убрать методы ```ОписаниеКоманды``` и ```ВыполнитьКоманду```, и создать поля класса, с необходимыми аннотациями, и метод с аннотацией ```&ВыполнениеКоманды```.

Expand All @@ -245,13 +270,13 @@
КонецПроцедуры

Процедура ОписаниеКоманды(Знач КомандаПриложения) Экспорт

КомандаПриложения.Опция("n name", "", "Имя пользователя");

КонецПроцедуры

Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт

ИмяПользователя = КомандаПриложения.ЗначениеОпции("name");

Сообщить("Привет " + ИмяПользователя);
Expand Down Expand Up @@ -279,5 +304,3 @@
## Больше примеров

Описанные классы можно посмотреть в каталоге [example](example/) и еще больше примеров команд в каталоге [tests](tests/Классы)


63 changes: 61 additions & 2 deletions src/Классы/ИКС_Рогатка.os
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
&Пластилин
Перем КонсольноеПриложение;

&Деталька(Значение = "cli.ПоказыватьСтекВызововПриОшибкеПриОшибке", ЗначениеПоУмолчанию = Истина)
nixel2007 marked this conversation as resolved.
Show resolved Hide resolved
Перем ПоказыватьСтекВызововПриОшибке;

Перем Лог;

Процедура ПриЗапускеПриложения() Экспорт
Expand All @@ -12,7 +15,15 @@
Попытка
КонсольноеПриложение.Запустить(АргументыКоманднойСтроки);
Исключение
Лог.Ошибка(ОписаниеОшибки());
Если ПоказыватьСтекВызововПриОшибке Тогда
ПодробныйСтекВызовов = СтекВызововСтрокой(ИнформацияОбОшибке());
// основную ошибку покажем ниже стека вызовов, чтобы пользователю не пришлось скроллить
Лог.Ошибка("Стек трейс:
|%1
|%2", ПодробныйСтекВызовов, ОписаниеОшибки());
Иначе
Лог.Ошибка(ОписаниеОшибки());
КонецЕсли;

ВременныеФайлы.Удалить(); // todo: перехватчик "ПриЗавершенииПриложения" в ОСени?

Expand All @@ -26,4 +37,52 @@
&Рогатка(ЗапускатьВФоне = Ложь)
Процедура ПриСозданииОбъекта()
Лог = Логирование.ПолучитьЛог("oscript.lib.autumn-cli");
КонецПроцедуры
КонецПроцедуры

// Получить стек вызовов строкой для выдачи в логи
//
// Параметры:
// ИнформацияОбОшибке - ИнформацияОбОшибке - ошибка
// ИсключатьСтекОсени - Булево - исключать стек вызовов библиотек ОСени или нет
//
// Возвращаемое значение:
// Строка
//
Функция СтекВызововСтрокой(Знач ИнформацияОбОшибке, Знач ИсключатьСтекОсени = Истина)
СтекВызовов_ = ИнформацияОбОшибке.ПолучитьСтекВызовов();
МассивТекстИсключения = Новый Массив;

Отступ = "";
СимволОтступа = " ";
ПервыйКадр = Истина;
Для Каждого КадрСтекаВызовов Из СтекВызовов_ Цикл
// пропустим первый кадр стека, т.к. он ведет на служебный вызов исключения
Если ПервыйКадр Тогда
ПервыйКадр = Ложь;
Продолжить;
КонецЕсли;

Если ИсключатьСтекОсени И ЭтоКадрСтекаИзОсени(КадрСтекаВызовов) Тогда
Прервать;
КонецЕсли;

Отступ = Отступ + СимволОтступа;

СтрокаСтекТрейса = СтрШаблон(
"%1%2 / Метод %3 / Строка %4",
Отступ,
КадрСтекаВызовов.ИмяМодуля,
КадрСтекаВызовов.Метод,
Формат(КадрСтекаВызовов.НомерСтроки, "ЧГ=")
);
МассивТекстИсключения.Добавить(СтрокаСтекТрейса);
КонецЦикла;

Возврат СтрСоединить(МассивТекстИсключения, Символы.ПС);

КонецФункции

Функция ЭтоКадрСтекаИзОсени(КадрСтекаВызовов)
Возврат СтрНачинаетсяС(КадрСтекаВызовов.Метод, "ДекораторВнутренний_")
И СтрНачинаетсяС(КадрСтекаВызовов.ИмяМодуля, "<string");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@artbear получится поковырять ещё?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется, можно ограничиться классом ЗапускательПриложения

КонецФункции