Давайте для простоты предположим, что у меня есть простая функция, которая просто пытается открыть файл на основе строки, переданной в качестве параметра (не полагайтесь на простоту процесса открытия файла, учитывая, что фактический пример будет более запутанным )
func retrieveConfig(fs billy.Filesystem, app string) (Spec, error) {
var v Spec
filename := "releases/" + app + ".yaml"
file, err := fs.Open(filename)
if err != nil {
errOpenFile := ErrOpeningConfigFile{filename}
return Spec{}, new errOpenFile{filename}
}
Вот определение пользовательской ошибки, которую я использую
type ErrOpeningConfigFile struct {
s string
}
func (errConfigFileNotFound *ErrOpeningConfigFile) Error() string {
return fmt.Sprintf("Error opening configuration file %s")
}
Я подумал о том, чтобы следовать этому подходу, потому что моя идея состоит в том, что он даст больший охват и сделает ядро более тестируемый.
Теперь я могу более легко тестировать пути ошибок, учитывая, что я могу печатать assert для пользовательской ошибки в моих модульных тестах.
Однако это определенно увеличивает базу кода.
Я полагаю, что наоборот - просто
return nil, errors.New("Configuration file not found")
, который ограничил бы код, но сделал бы тестирование более громоздким (или более узким, ограниченным).
Что является подходящим (или Go идиоматический c способ) об этом?