Функция должна заканчиваться возвратом

Скрытый возврат значений из функции - зло или благо?

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

Можно написать такой код:

Функция Тест()
  Сообщить("Привет, мир!");
КонецФункции

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

Функция Тест()
  Сообщить("Привет, мир!");
  Возврат Неопределено;
КонецФункции

Что же в этом плохого? К сожалению, такое заботливое поведение может "подложить свинью" в случаях, когда программист ошибся в логике своего кода. Например:

// Определяет один из банковских счетов организации.
//
// Параметры:
//   Организация - СправочникСсылка.Организации - организация;
//   Банк - ОпределяемыйТип.БанкОбменСБанками - банк.
//
// Возвращаемое значение:
//   СправочникСсылка.БанковскиеСчета - банковский счет.
//
Функция БанковскийСчет(Знач Организация, Знач Банк)
  
  МассивБанковскихСчетов = Новый Массив;
  ПолучитьБанковскиеСчета(Организация, Банк, МассивБанковскихСчетов);
  Если МассивБанковскихСчетов.Количество() Тогда
    Возврат МассивБанковскихСчетов[0];
  КонецЕсли;
  
  // Здесь вернется Неопределено!
КонецФункции

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

Исправить такой код очень просто, необходимо исходить из пессимистичных сценариев и ожидать, что если что-то плохое может произойти, оно обязательно произойдет:

Функция БанковскийСчет(Знач Организация, Знач Банк)
  
  МассивБанковскихСчетов = Новый Массив;
  ПолучитьБанковскиеСчета(Организация, Банк, МассивБанковскихСчетов);
  Если МассивБанковскихСчетов.Количество() Тогда
    Возврат МассивБанковскихСчетов[0];
  КонецЕсли;
  
  Возврат Справоченики.БанковскиеСчета.ПустаяСсылка();
КонецФункции

Как этого можно было избежать:

  • не верить всему, что написано в документации к методу и лично проверять, что возвращает функция;
  • тщательно тестировать свои доработки/исправления. Даже если у вас нет автотестов или QA, разработчик не должен лениться самостоятельно запустить и проверить свою доработку;
  • использование статических анализаторов/линтеров, которые могут в автоматическом режиме проверить все возможные варианты возврата из функции и указать на упущенные кейсы.