☄️ Проверка качества кода 1С
Функция должна заканчиваться возвратом
Во встроенном языке платформы 1С есть множество вещей, которые призваны облегчить работу программиста. Например, необязательный возврат значения из функции.
Можно написать такой код:
Функция Тест()
Сообщить("Привет, мир!");
КонецФункции
и он успешно пройдет валидацию компилятора, несмотря на отсутствие оператора "Возврат". В случаях когда в функциях отсутствует явный оператор "Возврат", платформы 1С скрыто добавляет возврат значения "Неопределено". То есть код выше на самом деле выглядит так:
Функция Тест()
Сообщить("Привет, мир!");
Возврат Неопределено;
КонецФункции
Что же в этом плохого? К сожалению, такое заботливое поведение может "подложить свинью" в случаях, когда программист ошибся в логике своего кода. Например:
// Определяет один из банковских счетов организации.
//
// Параметры:
// Организация - СправочникСсылка.Организации - организация;
// Банк - ОпределяемыйТип.БанкОбменСБанками - банк.
//
// Возвращаемое значение:
// СправочникСсылка.БанковскиеСчета - банковский счет.
//
Функция БанковскийСчет(Знач Организация, Знач Банк)
МассивБанковскихСчетов = Новый Массив;
ПолучитьБанковскиеСчета(Организация, Банк, МассивБанковскихСчетов);
Если МассивБанковскихСчетов.Количество() Тогда
Возврат МассивБанковскихСчетов[0];
КонецЕсли;
// Здесь вернется Неопределено!
КонецФункции
В примере выше разработчик исходит из утверждения, что массив банковских счетов для организации будет всегда заполнен. Даже в документации по возвращаемому значению он уверено написал, что возвращаться будет всегда ссылка. Однако если этим методом воспользуется другой человек, уверенный, что к нему вернется ссылка (ведь документация к методу не может обманывать!) и передаст в параметры организацию для которой нет банковских счетов (организацию завели, а банковские счета ещё не загрузили), то с высокой долей вероятности при работе со значением будет неинформативная ошибка времени выполнения, на расследование и исправление которой уйдет достаточно большое количество времени.
Исправить такой код очень просто, необходимо исходить из пессимистичных сценариев и ожидать, что если что-то плохое может произойти, оно обязательно произойдет:
Функция БанковскийСчет(Знач Организация, Знач Банк)
МассивБанковскихСчетов = Новый Массив;
ПолучитьБанковскиеСчета(Организация, Банк, МассивБанковскихСчетов);
Если МассивБанковскихСчетов.Количество() Тогда
Возврат МассивБанковскихСчетов[0];
КонецЕсли;
Возврат Справочники.БанковскиеСчета.ПустаяСсылка();
КонецФункции
Как этого можно было избежать:
* не верить всему, что написано в документации к методу и лично проверять, что возвращает функция;
* тщательно тестировать свои доработки/исправления. Даже если у вас нет автотестов или QA, разработчик не должен лениться самостоятельно запустить и проверить свою доработку;
* использование статических анализаторов/линтеров, которые могут в автоматическом режиме проверить все возможные варианты возврата из функции и указать на упущенные кейсы.
P.S. Что может пойти не так
в этом коде ? 😃