воскресенье, 22 ноября 2020 г.

Go style guides: не используйте panic

Код, запущенный в продуктовой среде, должен избегать паники. Паника - главный источник каскадных сбоев. В случае возникновения ошибки функция должна вернуть ошибку и позволить вызывающему абоненту решить, как ее обработать.

Неудачный вариант:

func run(args []string) {
    if len(args) == 0 {
        panic("требуется аргумент")
    }
    // ...
}

func main() {
    run(os.Args[1:])
}

Более удачный вариант:

func run(args []string) error {
    if len(args) == 0 {
        return errors.New("требуется аргумент")
    }
    // ...
    return nil
}

func main() {
    if err := run(os.Args[1:]); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

Panic/recover не является стратегией обработки ошибок. Программа должна паниковать только тогда, когда происходит что-то безвозвратное, например, нулевое разыменование (nil dereference, попытка получить значение по nil адресу, например в ситуации когда переменная с типом указателя структуры содержит nil и происходит попытка разыменования указателя). Исключением является инициализация программы: плохие вещи при запуске программы, которые должны прервать выполнение программы, могут вызвать panic.

var _statusTemplate = template.Must(
     template.New("name").Parse("_statusHTML"))

Даже в тестах предпочтительнее паники t.Fatal или t.FailNow, чтобы тест был отмечен как неудачный.

Неудачный вариант:

// func TestFoo(t *testing.T)

f, err := ioutil.TempFile("", "test")
if err != nil {
    panic("не удалось настроить тест")
}

Более удачный вариант:

// func TestFoo(t *testing.T)

f, err := ioutil.TempFile("", "test")
if err != nil {
    t.Fatal("не удалось настроить тест")
}


Читайте также:


Комментариев нет:

Отправить комментарий