Идиоматический способ обработки логической ошибки против ошибки программирования в golang - PullRequest
0 голосов
/ 08 июня 2018

Я использовал golang для автоматизации некоторых процессов развертывания, и мне пришлось использовать пакет exec для вызова некоторых скриптов bash.

Я использовал exec.Command("/home/rodrigo/my-deploy.sh").CombinedOutput() и увидел его реализацию

func (c *Cmd) CombinedOutput() ([]byte, error) {
    if c.Stdout != nil {
        return nil, errors.New("exec: Stdout already set")
    }
    if c.Stderr != nil {
        return nil, errors.New("exec: Stderr already set")
    }
    var b bytes.Buffer
    c.Stdout = &b
    c.Stderr = &b
    err := c.Run()
    return b.Bytes(), err
}

Я понял, что вы не можете назначить c.Stdout при использовании CombinedOutput(), и я думаю, что это нормально, но способ информирования об этом api-вызывающего абонента неверен.

CombinedOutput() возвращает ошибку, когдавы используете его неправильно, поэтому, если вы собираетесь использовать CombinedOutput(), вам не следует назначать c.Stderr или c.Stdout ранее, если вы это сделаете, то получите сообщение об ошибке.

Но эта ошибка не в том, что ваш скрипт выдает ошибку, а в том, что вы неправильно используете API, в этом случае я считаю, что вы должны получить panic, потому что неправильное использование API не должно обрабатываться (Я думаю).

Я пришел из мира Java, и когда вы используете какой-то метод неправильным образом, вы получите RuntimeException, например.

public void run(Job job) throws NotCompletedJob {
    if (job.getId() != null) {
        throw new IllegalArgumentException("This job should not have id");
    }
    job.setId(calculateId());
    job.run();
}

С этой подписью яможет знать, что я ошибаюсь, вызывая run(obj); с заданием, у которого есть идентификатор, и на самом деле я могу определить, есть ли ошибка в моем скрипте или я неправильно использую api.

NotCompletedJob это проверенное исключение, поэтому я должен его обработать, но IllegalArgumentException не так, чтобы я мог получить его в любое время.Поймать IllegalArgumentException или любой другой RuntimeException не всегда считается хорошей практикой, поскольку они указывают на то, что у вас есть ошибка с точки зрения программистов, и это не является вероятной ожидаемой ошибкой, такой как NotCompletedJob.

Наличиесказал, что, как я могу отличить программную ошибку (например, неправильное использование API) от ожидаемой ошибки (сценарий не завершился нормально) с текущей реализацией CombinedOutput()?

Чтобы прояснить мою проблему, я 'Я не говорю, что это неправильная текущая реализация CombinedOuput, но я не понимаю, как вызывающий может отличить, если это ошибка выполняемой команды или ошибка, вызванная неправильным использованием API.

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

1 Ответ

0 голосов
/ 08 июня 2018

Я пришел из мира Java, и когда вы используете какой-то метод неверным образом, вы получаете исключение RuntimeException.


Вы находитесь в мире Go сейчас.Следовательно, этот аргумент недействителен.Отказаться от Java.


Спецификация языка программирования Go

Обработка паники

Два встроенныхфункции, паника и восстановление, помогают в составлении отчетов и обработке паники во время выполнения и определенных при ошибке состояний.

func panic(interface{}) 
func recover() interface{}

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


The Go Blog

Отсрочка, паника и восстановление

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

На этой странице собраны общие комментарии, сделанные в ходе обзоров кода Go, так что короткие подробные ссылки могут ссылаться на одно подробное объяснение.Это список общих ошибок, а не руководство по стилю.

Не паникуйте

См. https://golang.org/doc/effective_go.html#errors. Не используйте панику для нормальной игрыобработка ошибок.Используйте ошибки и множественные возвращаемые значения.


Effective Go

Ошибки

Обычный способ сообщить об ошибке вызывающей стороне - это вернуть ошибку в качестве дополнительного возвращаемого значения.


Программа сервера Go одновременно обрабатывает 100 000 клиентов.Если возникает ошибка, сообщите и обработайте ее;всегда проверяйте на ошибки.НЕ сбой всех 100 000 клиентов с panic.Пакеты Go не должны panic.

Прочитать документацию Go и стандартный код библиотеки Go.

...