Использование Стека вызовов в качестве условия оператора Если [...] Тогда

14.10.22

Разработка - Механизмы платформы 1С

Делюсь интересным приёмом, позволяющим использовать данные стека исполнения кода 1С в качестве условия, накладываемого на выполнение кода.
 
 Рис.1 Пример визуализации стека в отладчике (но здесь не про отладчик будет идти речь)

Немного теории Стек вызовов - это инструмент, который показывает последовательность процедур и функций, исполнение которых привело к той строке модуля, что отлаживается сейчас. Стек большинство разработчиков используют при отладке исполнения кода. Также многие заметили, что начиная с платформы 8.3.15 в Журнал регистрации базы 1С и в операторе "Попытка ... Исключение ... КонецПопытки" возможно увидеть полный стек вызовов всех процедур, а не только вызов последней строки как было раньше (и this is хорошо).

Для начала расскажу как первый раз применил получение и разбор стека исполнения самим кодом 1С. В конец дам общий принцип по применению на практике.

Возникла проблема: При закрытии месяца в 1С: ERP, при выполнении операции "Формирование записей книг покупок и продаж" произошла ошибка: Операцию не удалось выполнить по причине того, что Отражение документов в регл учете невозможно поместить в запрещенный период. Дате 01.06.2019 соответствует запрет изменения данных для пользователя "Администратор (Михаил)" по 31.05.2020 (установлена общая дата запрета) 

Сформировалась задача, которую нужно было быстро сделать: Не нужно применять контроль даты запрета в случае выполнения операции "Формирование записей книг покупок и продаж" при закрытии месяца.

Приступив к решению задачи:

  • Отыскал исходную ошибку по Журналу регистрации 1С
 
 Рис.2 Ошибка в Журнале регистрации
 
 Текст ошибки со стеком вызова

При выполнении операции "Формирование записей книг покупок и продаж" произошла ошибка:
Не удалось выполнить по причине Отражение документов в регл учете невозможно поместить в запрещенный период.

Дате 01.06.2019 соответствует запрет изменения данных для пользователя "ГлавныйБухгалтерЗаместитель" по 29.02.2020 (установлена общая дата запрета)
{ОбщийМодуль.РеглУчетПроведениеСервер.Модуль(3509)}:        ВызватьИсключение ОписаниеОшибки;
{ОбщийМодуль.РеглУчетПроведениеСервер.Модуль(733)}:    ПроверитьДатуЗапретаДляОтраженияДокументовВРеглУчете(ШаблонЗапретаДанных);
{ОбщийМодуль.УчетНДСУПСлужебный.Модуль(9191)}:    РеглУчетПроведениеСервер.ВернутьДокументыКОтражению(ПараметрыРасчета.МенеджерВременныхТаблиц);
{ОбщийМодуль.УчетНДСУПСлужебный.Модуль(1602)}:    ВернутьДокументыКОтражениюВУчете(ПараметрыРасчета);
{ОбщийМодуль.УчетНДСУПСлужебный.Модуль(1588)}:    ВыполнитьРасчет(ПараметрыРасчета);
{ОбщийМодуль.УчетНДСУПСлужебный.Модуль(1506)}:            ВыполнитьРасчетСЗамеромВремени(ПараметрыРасчета);
{ОбщийМодуль.УчетНДСУП.Модуль(7742)}:    УчетНДСУПСлужебный.СформироватьЗаписиКнигиПокупокПродаж(КонецПериода, МассивОрганизаций, МассивСчетовФактур);
{ОбщийМодуль.ЗакрытиеМесяцаСервер.Модуль(13608)}:    УчетНДСУП.ВыполнитьЗаданияПоФормированиюКнигиПокупокПродаж(
{(1)}:ЗакрытиеМесяцаСервер.Выполнить_ФормированиеЗаписейКнигПокупокИПродаж(Параметры[0])
{ОбщийМодуль.ОбщегоНазначения.Модуль(4856)}:    Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";
{Обработка.ОперацииЗакрытияМесяца.МодульМенеджера(1558)}:                ОбщегоНазначения.ВыполнитьМетодКонфигурации(
{(1)}:Обработки.ОперацииЗакрытияМесяца.ВыполнитьРасчетЭтапов(Параметры[0])
{ОбщийМодуль.ОбщегоНазначения.Модуль(4856)}:    Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";

{ОбщийМодуль.УчетНДСУПСлужебный.Модуль(1526)}:            ВызватьИсключение ТекстСообщения;
{ОбщийМодуль.УчетНДСУП.Модуль(7742)}:    УчетНДСУПСлужебный.СформироватьЗаписиКнигиПокупокПродаж(КонецПериода, МассивОрганизаций, МассивСчетовФактур);
{ОбщийМодуль.ЗакрытиеМесяцаСервер.Модуль(13608)}:    УчетНДСУП.ВыполнитьЗаданияПоФормированиюКнигиПокупокПродаж(
{(1)}:ЗакрытиеМесяцаСервер.Выполнить_ФормированиеЗаписейКнигПокупокИПродаж(Параметры[0])
{ОбщийМодуль.ОбщегоНазначения.Модуль(4856)}:    Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";
{Обработка.ОперацииЗакрытияМесяца.МодульМенеджера(1558)}:                ОбщегоНазначения.ВыполнитьМетодКонфигурации(
{(1)}:Обработки.ОперацииЗакрытияМесяца.ВыполнитьРасчетЭтапов(Параметры[0])
{ОбщийМодуль.ОбщегоНазначения.Модуль(4856)}:    Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";

Открыл в конфигураторе ОбщийМодуль.РеглУчетПроведениеСервер строку № 3509 с текстом ВызватьИсключение ОписаниеОшибки;

Процедура ПроверитьДатуЗапретаДляОтраженияДокументовВРеглУчете(ШаблонЗапретаДанных, НаборЗаписей = Неопределено, ОтражаемыйДокумент = Неопределено)
	
	Если НаборЗаписей = Неопределено Тогда
		Отбор = Новый Структура;
		НаборЗаписей = Новый Структура("Регистр, Отбор", "РегистрСведений.ОтражениеДокументовВРеглУчете", Отбор);
	Иначе
		НаборЗаписей.ДополнительныеСвойства.Вставить("ПроверкаДатыЗапретаИзменения", Ложь);
	КонецЕсли;
	
	ОписаниеДанных = Новый Структура("НоваяВерсия, Данные", Истина, НаборЗаписей);
	ОписаниеОшибки = "";
	Если ДатыЗапретаИзменения.НайденЗапретИзмененияДанных(ШаблонЗапретаДанных, ОписаниеДанных, ОписаниеОшибки) Тогда
	
		ЗаписьЖурналаРегистрации(
			НСтр("ru = 'Установка нового статуса отражения в учете';
				|en = 'Set new status of recording in accounting'", ОбщегоНазначенияКлиентСервер.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка,
			?(ОтражаемыйДокумент = Неопределено, ОтражаемыйДокумент, ОтражаемыйДокумент.Метаданные()),
			?(ОтражаемыйДокумент = Неопределено, ОтражаемыйДокумент, ОтражаемыйДокумент),
			ОписаниеОшибки);
		
		ВызватьИсключение ОписаниеОшибки;
		
	КонецЕсли;
	
КонецПроцедуры

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

  • В поисках решения сразу пришли мысли: протянуть из обработки закрытия какой-нибудь параметр функции или сделать некий глобальный признак. Стал смотреть стек вызовов всех процедур (см. выше блок "Текст ошибки со стеком вызова")

читаю в нём:

....

ЗакрытиеМесяцаСервер.Выполнить_ФормированиеЗаписейКнигПокупокИПродаж(Параметры[0])

...

Обработки.ОперацииЗакрытияМесяца.ВыполнитьРасчетЭтапов

....

и тут загорается лампочка!

Можно ведь по тексту стека вызовов понять, что вызов идёт из закрытия месяца!

  • Нашёл, как получить стек вызовов в коде. Строку с данными стека вызовов можно получить только следующей комбинацией ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()). Причем отдельно в ИнформацияОбОшибке() данных о стеке не содержится, она загадочным образом достается только функцией ПодробноеПредставлениеОшибки().
Попытка

      ВызватьИсключение "Любой текст";

Исключение
		
      ПолныйТекстОшибкиВключаяСтекВызовов = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		
КонецПопытки;
  • Далее создал расширение конфигурации, в которое перетащил процедуру &Вместо("ПроверитьДатуЗапретаДляОтраженияДокументовВРеглУчете") из ОбщийМодуль.РеглУчетПроведениеСервер. Описал условие Если [...] Тогда, где поиском выражений-маркеров в полном тексте ошибки понимаю, что идёт вызов этапа формирования книг из обработки закрытия месяца и не применяю контроль даты запрета.
 
 Код из расширения

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

 

Какой могу сделать вывод в заключение:

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

 

Попытка

   ВызватьИсключение "Любой текст";
			
Исключение
		
   ПолныйТекстОшибкиВключаяСтекВызовов = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		
   Если Найти(ПолныйТекстОшибкиВключаяСтекВызовов, "Выражение-маркер 1") > 0
        И ... 
	И Найти(ПолныйТекстОшибкиВключаяСтекВызовов, "Выражение-маркер N") > 0 Тогда
	
       //Исполняемый код 1

   Иначе

       //Исполняемый код 2

   КонецЕсли;

КонецПопытки;

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

Основная мысль заложенная в данную публикацию это ИДЕЯ как вытащить дерево стека в сам исполняемый код, идея которую можно положить себе в ячейку памяти. Возможно она пригодиться!

На практике такой приём позволяет зашить часть возможностей отладки в СВОЙ КОД 1С, чтобы он получал и анализировал дерево стека и направлял алгоритм в разные ветки, в зависимости от наличия в тексте стека вызова определенных процедур (выражений-маркеров).

 

 
 Другие публикации автора

Ссылка на компетенции по 1С:ERP - команда со знаниями, умениями и успешными проектами.

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    3643    dsdred    48    

66

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5045    YA_418728146    25    

62

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6175    dsdred    36    

110

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    18206    SeiOkami    46    

116

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    11784    human_new    27    

72

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8569    YA_418728146    6    

139

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6207    sebekerga    54    

93

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15554    SeiOkami    31    

103
Отзывы
3. tormozit 7133 13.07.20 07:34 Сейчас в теме
Опасный прием. Но в плане быстрой и компактной модификации кода поставщика действительно может быть оправдано. Если уж применять, то надо
1. Обязательно проверять минимальную версию платформы
2. На большой глубине стека избегать применения в частотном коде, т.к. затраты на сборку полной строки стека могут стать заметными.
user619846_n.taradanov; fatman78; Deslime; ardn; GreenDragon; bulpi; Quasar; Dach; awk; Plotks2017; triviumfan; lmnlmn; dmryzhkov; sapervodichka; +14 Ответить
65. Mx00 247 16.03.23 05:11 Сейчас в теме
Очень пригодилось, благодарю :-)
добавлю свои "5 копеек" для чего это нужно - Конфигурация на поддержке и настраивается только расширениями
для каких-то общий модулей нужно реализовать принцип "тут играть, тут не играть" - со стеком вызова это сделать гораздо проще, а главное меньше приходится использовать "&ИзменениеИКонтроль"
sapervodichka, исправь в тексте для платформ с после 8.3.17
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
раз уж 1С так рекомендует :-)
sapervodichka; +1 Ответить
Остальные комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. rabid_otter 134 13.07.20 00:27 Сейчас в теме
Простите, но, по-моему, это жуткий костыль.
vld_dmn; Monte Carlo; GreenDragon; dabu-dabu; zqzq; webester; Brawler; vladimirmatancev; Dach; Quasar; IgorS; Yashazz; denmax; Артано; maksa2005; BaphoBush; +16 5 Ответить
2. tindir 13.07.20 05:57 Сейчас в теме
И мне так кажется, что это костылина, с первого взгляда. Выгладит как граница с вороватым таможенником - "эээээ, братъ, прхди, дорогой! А ты стой тут, ты пришел не с нашего района".
Интересен диаметр глаз кодера, который потом наткнется на этот код, когда будет разбирать ситуацию с тем что "восстановление последовательности зафигачило" закрытие пятилетней давности.

Стек вызово это ИМХО аналитический инструмент.
6. sapervodichka 6690 13.07.20 09:44 Сейчас в теме
(2) Вадим, привет, а со второго взгляда - тут прежде всего идея, о том как подтянуть дополнительные аналитики из стека исполнения кода. Не многие знают, что можно получить путь всех вызовов и использовать для анализа в самом коде. Например, есть задача починить в течение пары часов до обеда, а после обеда уже пользователи сдают результат руководству, или выплачивают зарплату в банк. Тут никто не думает о костыльности, а думает как сделать здесь и сейчас, и дополнительное знание такого варианта окажется возможной палочкой выручалочкой.
axsebur; user619846_n.taradanov; Andreyyy; tgr123; Upiterus; dmryzhkov; mikl79; SergeRSA; leonidy4; sasha777666; VKislitsin; +11 1 Ответить
10. Yashazz 4707 13.07.20 10:44 Сейчас в теме
(6) Вот именно из "починить за пару часов до обеда" и "ну всё ж работает, результат есть" и рождаются самые жуткие, самые опасные и самые впоследствии тяжело исправляемые костыли. Сам подход опасен.

Не расширения воротить надо по каждому поводу, а просто внимательно и вдумчиво отлаживаться.
13. sapervodichka 6690 13.07.20 12:10 Сейчас в теме
(10) Яков, я вот уверен, что половина даже не въехала в суть. Увидели знакомые слова Попытка Исключение и давай костылями махать. Яж не дурака тут пишу. НЕ В ОТЛАДКЕ ДЕЛО! Дело в возможности затащить стек исполнения в программируемый алгоритм.
21. Yashazz 4707 13.07.20 17:02 Сейчас в теме
(13) Я-то понял. Я именно про подход и что половина не въедет, а костылями махать начнёт. Возможность хитренькая и скользкая, с весьма узкими рамками применения, и при поверхностном чтении производит опасно-обманчивое впечатление.
Никогда ваши публикации не считал "дурака пишу", наоборот, они дельные, толковые и грамотные. Но конкретна эта - провокационна.
sapervodichka; +1 Ответить
24. sapervodichka 6690 13.07.20 17:17 Сейчас в теме
(21) как brr ниже написал, что будет совсем хорошо когда 1С вставит получение стека исполнения без вызова исключения
19. tindir 13.07.20 13:58 Сейчас в теме
(6)
окажется возможной палочкой выручалочкой

Извните, но это будет палочкой нафигвселомалочкой через полгода, когда все "срочные" отчеты уже сданы и забыты. А вот сейчас надо опять что-то сдать/заплатить.
Не надо апеллировать тем что это "временное" решенение, мы все знакомы с законом синей изоленты ;)
Артано; +1 Ответить
20. sapervodichka 6690 13.07.20 14:07 Сейчас в теме
(19) Вадим, ты забей, пожалуйста про исправление ошибки, ну вот не важно оно тут. Важен принцип, что можно текст ошибки со стеком получить и проанализировать самим же кодом.
Fox-trot; +1 Ответить
5. sapervodichka 6690 13.07.20 09:09 Сейчас в теме
(1) костыль это если в руках инвалида, а если в руках норм разраба, то это, конечно, не затычка для каждой дырки, а инструмент, который по делу, где нужно можно грамотно задействовать (лишь бы принцип был известен! а принцип я тут изложил, а в других публикациях я такой техники не встречал, так что ноги можно в другом месте о коврик обтирать, а тут подчерпнуть знаний)
Irwin; bulpi; leonidy4; Perfolenta; samir_27@list.ru; dmryzhkov; +6 Ответить
8. rabid_otter 134 13.07.20 09:49 Сейчас в теме
(5) как много лишних эмоций. хорошо, разверну ответ: допустим модуль A вызывает модуль B, а он в свою очередь модуль C. так вот в модуле C падает exception, и анализатор ошибки ищет модуль A в стеке вызовов. И внезапно модуль A переименовали, логика поменялась, а разраб, даже опытный забыл про этот костыль. В итоге система ломается, так как не соблюдается принцип инкапсуляции кода, насколько он возможен в 1C
Dach; Monte Carlo; Рамзес; +3 Ответить
9. sapervodichka 6690 13.07.20 09:55 Сейчас в теме
(8) ты всё правильно пишешь, как и многие другие доработки, эта может перестать работать (это жизнь от обновления к обновлению). Но посыл данной статьи другой, о возможности применить данные стека вызова в условиях в коде (она есть).
Рамзес; +1 Ответить
3. tormozit 7133 13.07.20 07:34 Сейчас в теме
Опасный прием. Но в плане быстрой и компактной модификации кода поставщика действительно может быть оправдано. Если уж применять, то надо
1. Обязательно проверять минимальную версию платформы
2. На большой глубине стека избегать применения в частотном коде, т.к. затраты на сборку полной строки стека могут стать заметными.
user619846_n.taradanov; fatman78; Deslime; ardn; GreenDragon; bulpi; Quasar; Dach; awk; Plotks2017; triviumfan; lmnlmn; dmryzhkov; sapervodichka; +14 Ответить
31. Brawler 453 14.07.20 12:11 Сейчас в теме
(3) А завтра 1С по другому данные стека будет показывать и все, приехали))
32. sapervodichka 6690 14.07.20 12:18 Сейчас в теме
(31) интересная позиция, тогда по твоей логике любой код завтра работать не будет, согласен? (1С постоянно всё меняет, а мы допиливаем и получаем зарплату)
33. sapervodichka 6690 14.07.20 12:25 Сейчас в теме
(32) я с позиции специфики нашей работы (тут код стабилен как и любая другая доработка... до очередного обновления релиза), доработка тут нормальная, не говнокод написанный из корыстных целей, а затем его поддержки. Не "а ля снимаем колеса и он наш"
34. Brawler 453 14.07.20 12:54 Сейчас в теме
(32)
1. как выше писали это костыли и притом неявные, другой разработчик не будет подозревать, что система так себя может вести
2. нельзя надеяться на то что и завтра "ЗакрытиеМесяцаСервер.Выполнить_ФормированиеЗаписейКнигПокупокИПродаж" будет так же называться
3. нельзя надеяться на то что формируемая строка в ПодробноеПредставлениеОшибки будет такого же формата, да и к тому же думаю она там малость и на разных языках может формироваться

я в своей практике стараюсь не опираться на жиденькие конструкции

а в последнее время блин превратился в бесплатного дебаггера ERP... писец качество продукта под номером 2.4.12.75 ... пока пытаешься воспроизвести одну ошибку, по пути еще пару находишь

Вот сегодня новая встретилась в заказе клиента, Онлайн взаиморасчеты...

Ошибка при выполнении обработчика - 'ОбработкаПроведения'
по причине:
Ошибка записи! Не установлен отбор по регистратору (Регистр сведений: Отражение документов в регл учете)
{ОбщийМодуль.ПроведениеСерверУТ.Модуль(433)}: Объект.Движения.Записать();
{Документ.ЗаказКлиента.МодульОбъекта(868)}: ПроведениеСерверУТ.ЗаписатьНаборыЗаписей(ЭтотОбъект);

по причине:
Ошибка при выполнении обработчика - 'ПриЗаписи'
по причине:
Ошибка записи! Не установлен отбор по регистратору (Регистр сведений: Отражение документов в регл учете)
{ОбщийМодуль.РеглУчетПроведениеСервер.Модуль(912)}: НаборЗаписей.Записать();
{ОбщийМодуль.РеглУчетПроведениеСервер.Модуль(1855)}: ВернутьДокументыКОтражению(МенеджерВременныхТаблиц);
{ОбщийМодуль.ОперативныеВзаиморасчетыСервер.Модуль(1259)}: РеглУчетПроведениеСервер.ЗарегистрироватьДокументыРасчетовСПартнерамиКОтражениюВРеглУ­чете(ТаблицаИзменений);
{ОбщийМодуль.ОперативныеВзаиморасчетыСервер.Модуль(1482)}: ЗаполнитьОперативныеВзаиморасчеты(ОсновныеПараметры);
{РегистрНакопления.РасчетыСКлиентами.МодульНабораЗаписей(631)}: ОперативныеВзаиморасчетыСервер.РассчитатьПоИзменениям(Запрос.МенеджерВременныхТаблиц, Истина, Отбор.Регистратор.Значение, ДополнительныеСвойства);
{ОбщийМодуль.ПроведениеСерверУТ.Модуль(433)}: Объект.Движения.Записать();
{Документ.ЗаказКлиента.МодульОбъекта(868)}: ПроведениеСерверУТ.ЗаписатьНаборыЗаписей(ЭтотОбъект);

по причине:
Ошибка записи! Не установлен отбор по регистратору (Регистр сведений: Отражение документов в регл учете)
Показать
36. sapervodichka 6690 14.07.20 13:52 Сейчас в теме
(34) Я тут не писькой меряюсь, а пишу О ВОЗМОЖНОСТИ ОНЛАЙН ПОЛУЧАТЬ КОДОМ СТЭК ВЫЗОВОВ И КОДОМ ЖЕ ОНЛАЙН АНАЛИЗИРОВАТЬ. Повторю, что костыли у инвалидов (если "другой разработчик не будет подозревать, что система так себя может вести", значит он не умеет читать код и он не разработчик, а инвалид). И согласен с тобой, что "нельзя надеятся на завтра" т.к. большая часть твоего кода из ERP 2.4 не будет в ERP 2.5 работать.
37. sapervodichka 6690 14.07.20 13:59 Сейчас в теме
(36) те кто пишет, что это костыль, просто почитали и не поняли. Почитай комменты 98% альтернативного решения определить на лету место вызова в коде не могут предложить, только со стула могут пЁрнуть
35. tormozit 7133 14.07.20 13:24 Сейчас в теме
(31) Ну про то, что нужно сделать опознание формата вывода стека, я думал итак понятно хорошему программисту. При изменении формата нужно выбрасывать исключение. К тому же этот формат меняться не будет с большой вероятностью навсегда (в пользу этого говорит история платформы 1С). Из-за очень низкой вероятности этого изменения, этим уже можно и пренебречь в частных случаях, для которых предлагается этот прием.
sapervodichka; +1 Ответить
40. Артано 759 20.07.20 07:37 Сейчас в теме
(3) Не согласен. Объем усилий по ограждению этого фрагмента сигнальными флажками типа "Осторожно мины" сопоставим с конвенционными методами исправления. Такой подход может иметь место максимум для понимания где именно причина проблемы, то есть как часть отладки в процессе разработки.
Выпускать в релиз такое решение без соответствующей изоляции и документирования чреват более серьезными проблемами, особенно в условиях коллективной разработки.
57. Froloid 66 07.02.22 19:40 Сейчас в теме
(40)
Такой подход может иметь место максимум для понимания где именно причина проблемы, то есть как часть отладки в процессе разработки


А этого более чем достаточно (именно для этого и используется стек вызовов). Автор красавчик.
Andreyyy; +1 Ответить
50. tormozit 7133 29.09.20 10:07 Сейчас в теме
(3) Еще в обычном приложении стек до сих пор не формируется в описании ошибки (проверено на 8.3.18). Так что и здесь могут возникнуть отличия.
4. Алексей Воробьев 291 13.07.20 08:32 Сейчас в теме
Вполне годно для ограниченного применения - в рамках конкретной задачи в конкретной организации.
Масштабировать такие решения, наверное, будет не совсем правильно. А, в связи с этим, и проверять минимальную версию платформы не обязательно - вероятность отката платформы для продуктовых баз невелика...
Fox-trot; bulpi; dmryzhkov; sapervodichka; +4 Ответить
7. Darklight 32 13.07.20 09:46 Сейчас в теме
Присоединяюсь к вышесказанному. В данном случае - почти годно. Надо только понимать - что обработка исключений - дело затратное по-производительности - и всюду вставлять вставки как на первом скриншоте (т.е. специально генерируя исключение, чтобы получить стек вызова) - может дать сильное проседание производительности - так что это скорее уж очень специальный приём - не для всех! Другое дело - когда (как далее по тексту) исключение и так уже создаётся - тогда да - данный финт можно применить.

Но.... надо понимать, что 1С постоянно тусует код типовых конфигураций - от чего названия модулей и процедур может меняться (полный путь) - а тут как раз идёт его анализ. Это не есть хорошо! Поэтому - тут тогда лучше делать всегда конкретные условия на ветки ветвления - без секции "Иначе" - вернее с ней - в неё должна быть генерация исключения - что ветка условия Вышла за границы условия и программисту нужно его пересмотреть!

Ну а я, всё-таки за то, чтобы передавать доп параметры через внешние переменные (обычно - параметры сеанса для управляемых приложений). Это куда надёжнее - заводишь такую переменную (параметр сеанса) типа "Соответствие"("ФиксированноеСоотвествие"), парой общих функций помещаешь и извлекаешь оттуда доп параметры для конкретной вложенной функции (по её имени, аргументу, и, возможно, дополнительной текстовой пометке-ограничению).

А вообще - для решения таких задач есть АОП - жаль в 1С его нет (хотя сами расширения - вообще-то это уже АОП - вот только очень ограниченный) - не хватает в 1С продвинутого АОП, очень не хватает...

Ну а данной статье очень не хватает приложения како-нибудь функции алгоритма - для продвинутого и чёткого разбора текста стека - а то как-то использовать функцию "Найти" по месту вызова - совсем не кошерно!
GV.; sapervodichka; +2 Ответить
11. Yashazz 4707 13.07.20 10:45 Сейчас в теме
Я для таких вещей написал конфигурацию анализа конфигураций и копаюсь через неё, как возникают подобные проблемы. Обычную трассировку скинул, разобрал, и всё. Элементарные выгрузки замера производительности в таб.документ никто не отменял, а там пошагово всё замечательно видно.
12. sapervodichka 6690 13.07.20 10:59 Сейчас в теме
(11) Яков, привет, точно дочитал? Представим конфигуратор закрыт, как сам кусок кода 1С исполняемый в некой процедуре получает у тебя Стек вызовов и определяет сам по условию Если Найти(ТекстСтека, "Выражение-маркер") > 0 Тогда какой блок текущей процедуры ему выполнять дальше.
22. Yashazz 4707 13.07.20 17:04 Сейчас в теме
(12) Дочитал, дочитал) Я одно время такую штуку пользовал - она выгружала код конфы в файлы, дописывала в нужные файлы примерно такое же, грузила обратно.
sapervodichka; +1 Ответить
23. sapervodichka 6690 13.07.20 17:15 Сейчас в теме
25. Yashazz 4707 13.07.20 19:47 Сейчас в теме
(23) Надеюсь, однажды мне разрешат её выложить на ИС, хотя бы урезанную. Тогда можно я твою идею в ней воплощу?
26. sapervodichka 6690 13.07.20 19:57 Сейчас в теме
(25) конечно =))) только помни, что когда твой ПО заработает пару млн $ я на тебя предъяву кину на компенсацию авторства )))
27. Yashazz 4707 13.07.20 22:33 Сейчас в теме
(26) Я сам первый тебе маякну. Хотя это всё чистейшая фантастика... Тут даже моя обработка, раскладывающая код на блок-схемы по ходу выполнения, и то набрала в своё время 4 плюса (юзал граф.схемы 1С, строил с анализом текста). Какие уж тут миллионы)))
AnryMc; sapervodichka; +2 Ответить
43. caponid 04.09.20 15:39 Сейчас в теме
(27) интересно про обработку.. а можно ткнуть ссылкой? а то через профиль ничего такого не нахожу)
44. Yashazz 4707 04.09.20 15:58 Сейчас в теме
(43) Уже нельзя. Я это решение вставил в одну из дорабатывавшихся мною конфигураций, правообладатель которой велел убрать публикацию.
64. kembrik 10 26.01.23 17:39 Сейчас в теме
(27) Эх жаль не успел, сейчас подобный велосипед изобретаю. Если вкратце - анализатор текста работает с модулями, которые предварительно через выгрузку в файл были сделаны или есть иной волшебный способ?

Или успел? Листаю https://infostart.ru/1c/articles/537353/
14. zhuntovda 1 13.07.20 13:20 Сейчас в теме
Хитро, но я бы не стал. Явный костыль. На заметку можно взять, но пользовать в крайнем случае, от слова никогда!
15. sapervodichka 6690 13.07.20 13:25 Сейчас в теме
(14) =))) пойду солью сертификат эксперта в унитаз. Критика-то должна быть обоснована. Предложи альтернативный способ как ты выяснишь в коде место стартового вызова для общего метода с большой вложенностью?
16. sapervodichka 6690 13.07.20 13:28 Сейчас в теме
(15) =))) наверняка также на лету будешь получать и разбирать путь из стека в коде
17. brr 182 13.07.20 13:33 Сейчас в теме
А потом у нас "В данной транзакции происходили ошибки", опасная штука предложена. 1С стоило бы добавить получение стека вызовов без таких костылей. А так идея - огонь.
Artem-B; zqzq; Yashazz; sapervodichka; +4 Ответить
18. sapervodichka 6690 13.07.20 13:36 Сейчас в теме
(17) да, это отличная идея, было бы круто с их стороны!
41. sapervodichka 6690 08.08.20 11:48 Сейчас в теме
(18) "В данной транзакции происходили ошибки" хороший контраргумент ))) но он не из этой оперы, точно не для описанного в публикации случая (там он просто невозможен!). И такая бяка всплывает обычно только для записи в попытке внутри уже открытых транзакций. При том значительная часть кода конфигураций выполняет вне транзакции, т.е. высказанное замечание на принцип не сильно влияет т.к. не идет отработки записи в попытке. Короче не так страшен черт как его малюют.
28. Aquashop 46 13.07.20 22:53 Сейчас в теме
Пример конечно интересный, но можно же было через замер производительности при старте закрытия увидеть весь выполняемый код и понять в чём проблема, разве нет?
29. sapervodichka 6690 13.07.20 23:06 Сейчас в теме
(28) как трассировать при закрытом конфигураторе?.. мысль тут не в разовой трассировке в отладчике и анализе кода, а в получение каждый раз онлайн кодом данных трассировки, и тем же самым кодом анализ этих данных и выбор дальнейших действий. Невозможно иначе в глубоко зарытой в модулях некой общей процедуре, вызываемой из десятков мест и имеющей кучу других предварительных вызовов иначе понять, откуда из интерфейса она вызвана.
Aquashop; +1 Ответить
30. Aquashop 46 13.07.20 23:31 Сейчас в теме
(29)Скорее всего не всё, но большая часть дошло))) Интересный вариант, надо попробовать потестить, должно существенно ускорить поиск по сравнению с замером. А вот выбор дальнейших действий по трассировке опасно но порой необходимо... Благодарю
sapervodichka; +1 Ответить
38. утюгчеловек 38 15.07.20 12:41 Сейчас в теме
39. sapervodichka 6690 15.07.20 12:53 Сейчас в теме
42. koof90 14.08.20 14:26 Сейчас в теме
Идея очень интересная, если использовать ее как инструмент отладки, особенно когда просто нет возможности вести живую трассировку из конфигуратора.
45. DrWeb3 71 22.09.20 13:48 Сейчас в теме
Очень полезная информация, но синтакс-помощник думает иначе:

-8<---------------------
Описание:
Возвращает строку, аналогичную той, что показывается в стандартном диалоге платформы "1С:Предприятие", вызываемом при нажатии кнопки "Подробно" из сообщения об ошибке.
.......
Не рекомендуется использовать, начиная с версии 8.3.17.
Описание изменено в версии 8.3.17.
-8<---------------------


Подозреваю, что 1С сознательно не дает программистам смотреть стек. А очень нужно, т.к. у меня например исключения шлются в виде запросов в helpdesk и было бы очень не плохо, чтобы разрабы там сразу видели стек, а не просто ошибку.
sapervodichka; +1 Ответить
46. sapervodichka 6690 22.09.20 13:52 Сейчас в теме
(45) я это на 8.3.16 прогонял, на 8.3.17 появился инструмент с подробным описанием ошибок в августе была статья https://infostart.ru/1c/articles/1275015/ может там найдёшь что-то полезное для себя
47. DrWeb3 71 22.09.20 14:33 Сейчас в теме
48. DrWeb3 71 22.09.20 15:59 Сейчас в теме
(46) К сожалению не совсем это то. У нас висят веб-сервисы, интеграции и т.д. Все это работает в фоне и когда от функции передачи информации на сервер например приходит исключение - хотелось бы видеть стек именно программно и отправить его автоматом разрабам, т.к. при этом нет никакого пользовательского окна.

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

Но я как бы понимаю, что вопрос не к вам, так что могу просто посетовать, что жаль такую возможность прикрыли
49. sapervodichka 6690 22.09.20 16:03 Сейчас в теме
(48) можно сделать периодические запросы к событиям Журнала регистрации, в них фиксируется полный стек ошибок.
51. GV. 1 02.12.20 19:00 Сейчас в теме
А вот я в свое время искал-обыскался, да не нашел способа программного получения стека вызовов. Спасибо автору!
Конечно, использовать надо крайне осторожно, но об этом уже и так достаточно наговорили.
По мне, так это крайне удивительно, что фактически 1С во время исполнения кода всегда хранит стек вызовов, но адекватного метода обращения к нему платформа не предоставляет... Почему, спрашивается?! 0_о

Однако, обнаружил, что метод ПодробноеПредставлениеОшибки(ИнформацияОбОшике()) может не выдавать полный стек. При этом, если убрать конструкцию Попытка-Исключение в режиме Предприятия по кнопке "Подробно" и в журнале регистрации по той же самой ошибке отображается полный стек.
У кого-нибудь есть идеи отчего такое может быть? И как можно добиться заявленной работы метода?

1С:Предприятие 8.3 (8.3.15.1830)
Документооборот 8 КОРП, редакция 2.1 (2.1.11.5)

В приведенном коде данный метод выдает только саму строку с ошибкой без полного стека вызовов:
	Попытка
		
		Тест = ЗаявкаСсылка.Автор; 
		
	Исключение
		Конфигурация 					= СтрШаблон("%1 (%2)", Метаданные.Имя, Метаданные.Версия);
		ВремяВозникновения 				= ТекущаяДатаСеанса();
		ОписаниеОшибки 					= ОписаниеОшибки();
		ПодробноеПредставлениеОшибки	= ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		
		Сообщить(	"В процессе отправки уведомления заявителю или проведения документа возникла ошибка.
					|Сообщите администратору нижеприведенное описание ошибки.");
		
		Сообщить(СтрШаблон(	"Конфигурация: %1. 
							|Время возникновения: %2. 
							|Описание ошибки:
							|%3. 
							|Подробное представление ошибки:
							|%4.",
							Конфигурация, ВремяВозникновения, ОписаниеОшибки, ПодробноеПредставлениеОшибки));

	КонецПопытки;
Показать


Переменная ПодробноеПредставлениеОшибки принимает следующее значение:
"Поле объекта не обнаружено (Автор)
{MY ОбщийМодуль.GV_ЗаявкиНаКорректировкуСтока.Модуль(168)}: Тест = ЗаявкаСсылка.Автор;"

Сообщение, кнопка "Подробно" и событие в журналие регистрации представлены на скриншотах.
Прикрепленные файлы:
sapervodichka; +1 Ответить
52. mrcamomile 79 07.01.21 20:38 Сейчас в теме
(51)
попробуй строчку
ПодробноеПредставлениеОшибки    = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
первой поставить в секции Исключение
kao_andi; Irwin; GV.; +3 Ответить
53. birk 116 17.11.21 10:05 Сейчас в теме
54. Gladkov_Anton 323 10.12.21 15:42 Сейчас в теме
(53) Это не работает.
Протестируйте в клиент-серверном варианте.
Будет не весь стек. Потратили на это кучу времени и получили кучу проблем.
Использовать получение стека через ИнформацияОбОшибке() можно только в файловой базе
55. artbear 1447 10.12.21 16:58 Сейчас в теме
(54) С чего вы это взяли??
возможность получения стека в подробном представлении доступна с 8.3.15 для любых ИБ.
sapervodichka; +1 Ответить
56. sapervodichka 6690 10.12.21 17:11 Сейчас в теме
(54) Скрины сверху, это всё из клиент-серверной базы, где 150 пользователей и размер 120 Гб - это точно не файловая )))) Всё норм работает, может ты просто в отладке файловой попадаешь в точку останова, а в клиент-серверной попасть не можешь .... (тогда включи в отладке возможность подключения к фоновым заданиям)
Прикрепленные файлы:
58. Gladkov_Anton 323 26.03.22 17:45 Сейчас в теме
Проверил еще раз на версии 8.3.18
Контекста клиента нет.
Прикрепленные файлы:
sapervodichka; +1 Ответить
59. sapervodichka 6690 26.03.22 23:06 Сейчас в теме
(58) спасибо, ценное замечание, по итогу работает, но в стек не попадают клиентские события, а только серверные. Я при решении проблемы маркеры на серверные строки ставил т.к. это был расчет себестоимости (там весь стек серверных вызовов). То что стек не полный (без клиента) - это очередная странность 1С, но для меня она роли не играла.
60. fixin 4252 31.03.22 17:42 Сейчас в теме
Я как-то искал возможнось получить стек и тоже пробовал этот метод. Но он то ли на клиенте только работает, то ли только на сервере, а мне нужно было на сервере.
61. sapervodichka 6690 31.03.22 19:05 Сейчас в теме
62. fixin 4252 31.03.22 22:02 Сейчас в теме
(61) ну вот задача у меня была отловить, когда записываются доп. реквизиты справочника номенклатуры и я пытался в при записи на сервере получить состояние стека и не мог его получить.
Правда у меня был такой код:
Попытка 
  а = 0/0;
Исключение
    Инфо = ИнформацияОбОшибке();
    Сообщить(НСтр("ru='Описание=';en='Description='") + Инфо.Описание + "'");
    Сообщить(НСтр("ru='ИмяМодуля=';en='ModuleName='") + Инфо.ИмяМодуля + "'");
    Сообщить(НСтр("ru='НомерСтроки=';en='LineNumber='") + Инфо.НомерСтроки + "'");
    Сообщить(НСтр("ru='ИсходнаяСтрока=';en='SourceLine='") + Инфо.ИсходнаяСтрока + "'");
КонецПопытки;
Показать


Сейчас попробовал вставить вместо ИнформацияОбОшибке эту функцию:
Попытка 
  а = 0/0;
Исключение
    Инфо = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    Сообщить(Инфо);
КонецПопытки;


Получил на клиенте:

Деление на 0
{(2)}: а = 0/0;
{ВнешняяОбработка.КонсольКода.Форма.Форма.Форма(40)}: Выполнить(ТекстДляВыполнения);
{ВнешняяОбработка.КонсольКода.Форма.Форма.Форма(60)}: ВыполнитьНаКлиенте();

На сервере:
Деление на 0
{(2)}: а = 0/0;
{ВнешняяОбработка.КонсольКода.Форма.Форма.Форма(13)}: Выполнить(ТекстДляВыполнения);


Ок, хороший метод, раньше я копал в вером направлении но не нагуглил эту функцию, спасибо
sapervodichka; +1 Ответить
63. user649357 08.08.22 09:26 Сейчас в теме
Интересный метод. Но есть особенности.
Кроме уже названной (что при вызове на сервере не виден клиентский стек), ПодробноеПредставлениеОшибки и ОбработкаОшибок.ПодробноеПредставлениеОшибки возвращает пустой стек, если метод вызван внутри модуля с установленным паролем или в поставке без коде.
sapervodichka; +1 Ответить
65. Mx00 247 16.03.23 05:11 Сейчас в теме
Очень пригодилось, благодарю :-)
добавлю свои "5 копеек" для чего это нужно - Конфигурация на поддержке и настраивается только расширениями
для каких-то общий модулей нужно реализовать принцип "тут играть, тут не играть" - со стеком вызова это сделать гораздо проще, а главное меньше приходится использовать "&ИзменениеИКонтроль"
sapervodichka, исправь в тексте для платформ с после 8.3.17
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
раз уж 1С так рекомендует :-)
sapervodichka; +1 Ответить
Оставьте свое сообщение