Имя: Пароль:
1C
1С v8
Достучаться до ВызватьИсключение
,
0 PuhUfa
 
23.11.19
12:18
УТ 11.4.7.150

В УТ, запись документа "заказ клиента", из формы, заворачивается через функцию ОМ:

Функция ОбработатьЗаписьОбъектаВФорме(Форма, ПараметрыЗаписи, Отказ = Ложь) Экспорт
    
    ДействиеПослеЗаписи = Неопределено;
    Если ПараметрыЗаписи.Свойство("ДействиеПослеЗаписи", ДействиеПослеЗаписи) Тогда
        ПараметрыЗаписи.Удалить("ДействиеПослеЗаписи");
    КонецЕсли;
    
    Результат = Ложь;
    
    Если Отказ Тогда
        Возврат Результат;
    КонецЕсли;
    
    НачатьЗамерВремениЗаписиОбъекта(Форма, ПараметрыЗаписи);
    Форма.НеВыполнятьПроверкуПередЗаписью = Истина;
    
    Отказ = Истина;
    ПараметрыЗаписи.Вставить(
        "ПринудительноЗакрытьФорму", Форма.ПринудительноЗакрытьФорму);
    ПараметрыЗаписи.Вставить("НовыйОбъект", Не ЗначениеЗаполнено(Форма.Объект.Ссылка));
    Результат = Форма.Записать(ПараметрыЗаписи);
    
    Форма.ПринудительноЗакрытьФорму = Ложь;
    Форма.НеВыполнятьПроверкуПередЗаписью = Ложь;
    
    Если Результат И ДействиеПослеЗаписи <> Неопределено Тогда
        ВыполнитьОбработкуОповещения(ДействиеПослеЗаписи, Результат);
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Нас интересует момент: Результат = Форма.Записать(ПараметрыЗаписи);

При проведении заказа, в событии ПриЗаписи() РН РасчетыСКлиентами вызывается:

ОписаниеОшибки = НСтр("ru = 'Изменяемые данные взаиморасчетов находятся в закрытом периоде.'");
ВызватьИсключение ОписаниеОшибки;

И пользователь получает окошко с: "Ошибка при вызове метода контекста (Записать)".
Если делать это в режиме отладки то ошибка будет:

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

Т.е. никакие "Изменяемые данные взаиморасчетов находятся в закрытом периоде." пользователь не получает и вынужден гадать что пошло не так. В ЖР ВызватьИсключение тоже ничего не пишет.

Если я оборачиваю в Попытку/исключение

Попытка
    Результат = Форма.Записать(ПараметрыЗаписи);
Исключение
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
    Результат = Ложь;
КонецПопытки;

то в таком варианте документ не проводится, ошибок никаких пользователь не получает, т.к. ОписаниеОшибки() возвращает пустую строку.

Вопрос, как в конкретной попытке/исключение достучаться до сообщения в ВызватьИсключение? Или это вообще не вариант и нужно переделывать текущий механизм?
1 acht
 
23.11.19
12:31
(0) Весьма похоже на то, что где-то есть еще одна попытка/исключение, которая гасит это исключение и просто устанавливает Отказ в обработчике в Истина.

Смотри глубже - Форма.Записать начинается с ПередЗаписью в форме, потому перед записью на сервере, потом в объекте, потом проведение и только потом где-то в регистре.
А, ну и еще при проверка заполнения - в форме и про проведении. И подписки.
2 PuhUfa
 
23.11.19
12:47
(1) Кроме моей Попытка/Исключения других нет.
Там при записи движений получается идет:
РегистрНакопления.РасчетыСКлиентами.МодульНабораЗаписей.ПриЗаписи(Отказ = Ложь, Замещение = Истина)
и внутри этого события вызывается:
РегистрНакопления.РасчетыСКлиентамиПоСрокам.МодульНабораЗаписей.ПриЗаписи(Отказ = Истина, Замещение = Истина)
в котором уже и происходит: ВызватьИсключение ОписаниеОшибки;

Возможно такая конструкция и "съедает" текст ОписаниеОшибки
3 Фрэнки
 
23.11.19
12:58
(2) все верно. У тебя поставлен внешний хук, а внутри этот хук сбивается уже другим хуком.
Это абсолютно похоже на реализацию обработки транзакций, когда срыв выполнения вложенной транзакции рушит все открытые вокруг нее внешние.
4 Фрэнки
 
23.11.19
13:00
зы. Хук - вот статья большая с разъяснениями зачем это все нужно в широком смысле :-)

https://habr.com/ru/company/infopulse/blog/140456/
5 PuhUfa
 
23.11.19
13:12
(4) Послал так послал -) Спс, почитаю.
6 acht
 
23.11.19
13:23
(5) Включи замер производительности. Наступи на ошибку. Выключи замер производительности. В списке выполнявшихся строк попробуй найти присвоение Отказ = Истина
7 PuhUfa
 
23.11.19
13:36
(6) Прям перед ВызватьИсключение:

ОписаниеОшибки = НСтр("ru = 'Изменяемые данные взаиморасчетов находятся в закрытом периоде.'");
Если ДатыЗапретаИзменения.НайденЗапретИзмененияДанных(ДанныеДляПроверки, ЭтотОбъект) Тогда
    Отказ = Истина;
    ВызватьИсключение ОписаниеОшибки;
КонецЕсли;
8 acht
 
23.11.19
13:41
(7) А теперь ставь там бряк и поднимайся вверх по стеку.
Причем, скорей всего, Отказ - это параметр процедуры и будет передаваться вверх автоматически.
9 strange2007
 
23.11.19
13:43
(0) Я всегда просто делаю - комментирую Попытку Исключение и смотрю ошибку. А искать механизмы флагов, анализировать логику и прочее, да ну его найиг. Как правило конструкция Попытка Исключение КонецПопытки находится вверху всего блока в одном месте. Закомментировал, глянул ошибку, раскомментировал.
10 PuhUfa
 
23.11.19
13:48
(8) Отказ это параметр события ПриЗаписи(Отказ, Замещение) РН "РасчетыСКлиентамиПоСрокам". Событие вызывается строкой: НаборЗаписейПоСрокам.Записать();
11 PuhUfa
 
23.11.19
13:51
(9) Так в том то и дело что Попытка/Исключения в типовом решении нет и пользователь получает на клиенте ошибку: "Ошибка при вызове метода контекста (Записать)". Из которой нифига ему не понятно. ВызватьИсключение "Изменяемые данные взаиморасчетов находятся в закрытом периоде" - до пользователя не долетает. Это я уже с отладчиком докопал до этого места. Вот теперь думаю как поправить, что бы пользователь видел не просто ошибку а причину ошибки.
12 acht
 
23.11.19
13:53
(9) > А искать механизмы флагов, анализировать логику и прочее, да ну его найиг.

Прелесть-то какая.
13 strange2007
 
23.11.19
14:18
(12) КД2. Ошибка. Я поначалу, когда изучал её, сутками сидел, разбирая и ища места, где что отваливается. Рисовал схемы, делал пометки. А потом плюнул и при ошибке просто комментировал Попытку. Несколько суток и 15 минут, есть разница? Думаю да
14 Сияющий в темноте
 
24.11.19
01:02
форма.записать - вызывает запись в форме
а в регистр идет запись при проведении документа.
15 runoff_runoff
 
24.11.19
08:08
по идее ВызватьИсключение ВСЕГДА пишет в ЖР
16 PuhUfa
 
24.11.19
08:21
(15) ну вот почему то нет -(
17 runoff_runoff
 
24.11.19
08:29
(16) в конфигураторе надо смотреть ЖР, там полный
18 runoff_runoff
 
24.11.19
08:31
(16) если ВызватьИсключение внутри Попытки, то не пишет в ЖР
19 Фрэнки
 
24.11.19
10:06
естественно, что не запишет в жр
20 Волшебник
 
24.11.19
10:25
Если дата < датыЗапреты Тогда
   Сообщить("бла-бла-бла");
   Отказ = Истина;
КонецЕсли;
21 PuhUfa
 
24.11.19
10:39
(18) Вот запись ЖР в стоковом варианте баз моего оборачивания в Попытка/Исключения
https://sun9-42.userapi.com/c857720/v857720476/fddab/-uk5PXNst_0.jpg
(20) Это понятно и логично. Но боюсь, что подобных мест в конфигурации будет достаточно и править каждое место... Хотя других вариантов пока все равно нет.
22 Cyberhawk
 
24.11.19
11:02
"как в конкретной попытке/исключение достучаться до сообщения в ВызватьИсключение?" // Если код, в котором выполняется ВызватьИсключение с текстовым описанием, обернут в попытку, то в общем случае никак
23 Cyberhawk
 
24.11.19
11:02
+(22) без доработки кода никак
24 Волшебник
 
24.11.19
11:04
(21) Просто это правильнее. Если программа может штатно обработать ситуацию запрета, то лучше так и сделать, а не вызывать исключение.
Ошибка? Это не ошибка, это системная функция.