Estou apenas começando com Go. Meu código está começando a ter muito disso:
if err != nil {
//handle err
}
ou isto
if err := rows.Scan(&some_column); err != nil {
//handle err
}
Existem boas expressões idiomáticas / estratégias / melhores práticas para verificar e lidar com erros no Go?
EDIT para esclarecer: não estou reclamando ou sugerindo que a equipe Go venha com algo melhor. Estou perguntando se estou fazendo certo ou se perdi alguma técnica que a comunidade criou. Obrigado a todos.
Respostas:
Seu código é idiomático e, em minha opinião, é a melhor prática disponível. Alguns discordariam com certeza, mas eu diria que esse é o estilo visto em todas as bibliotecas padrão em Golang . Em outras palavras, os autores de Go escrevem o tratamento de erros dessa maneira.
fonte
Seis meses depois que essa pergunta foi feita, Rob Pike escreveu uma postagem no blog intitulada Erros são valores .
Lá ele argumenta que você não precisa programar da maneira apresentada pelo OP e menciona vários lugares na biblioteca padrão onde eles usam um padrão diferente.
É uma boa leitura.
fonte
Eu concordaria com a resposta do jnml de que ambos são códigos idiomáticos e adicionaria o seguinte:
Seu primeiro exemplo:
é mais idiomático ao lidar com mais de um valor de retorno. por exemplo:
Seu segundo exemplo é uma boa abreviatura ao lidar apenas com o
err
valor. Isso se aplica se a função retornar apenas umerror
ou se você ignorar deliberadamente os valores retornados diferentes deerror
. Por exemplo, às vezes é usado com as funçõesReader
eWriter
que retornam umint
do número de bytes gravados (às vezes informações desnecessárias) e umerror
:A segunda forma é conhecida como o uso de uma instrução de inicialização if .
Portanto, com relação às melhores práticas, até onde eu sei (exceto pelo uso do pacote "errors" para criar novos erros quando você precisar deles), você cobriu praticamente tudo o que precisa para saber sobre os erros no Go!
EDIT: Se você descobrir que realmente não pode viver sem exceções, você pode imitá-los com
defer
,panic
&recover
.fonte
Fiz uma biblioteca para agilizar o tratamento de erros e canalizar uma fila de funções Go.
Você pode encontrá-lo aqui: https://github.com/go-on/queue
Possui uma variante sintática compacta e detalhada. Aqui está um exemplo para a sintaxe curta:
Esteja ciente de que há uma pequena sobrecarga de desempenho, uma vez que faz uso de reflexão.
Além disso, este não é um código go idiomático, então você vai querer usá-lo em seus próprios projetos ou se sua equipe concordar em usá-lo.
fonte
Uma "estratégia" para lidar com erros em golang e em outras linguagens é propagar erros continuamente pela pilha de chamadas até que você esteja alto o suficiente na pilha de chamadas para lidar com esse erro. Se você tentou lidar com esse erro muito cedo, provavelmente acabará repetindo o código. Se você lidar com isso tarde demais, você quebrará algo em seu código. Golang torna esse processo muito fácil, pois torna muito claro se você está lidando com um erro em um determinado local ou propagando-o.
Se você for ignorar o erro, um simples _ revelará esse fato muito claramente. Se você estiver lidando com isso, então exatamente qual caso do erro você está lidando é claro, pois você verificará na instrução if.
Como as pessoas disseram acima, um erro é na verdade apenas um valor normal. Isso o trata como tal.
fonte
Os deuses Go publicaram um "projeto de projeto" para tratamento de erros no Go 2. O objetivo é mudar o idioma dos erros:
Visão geral e design
Eles querem feedback dos usuários!
Wiki de feedback
Resumidamente, parece:
ATUALIZAÇÃO: o projeto de rascunho recebeu muitas críticas, então eu elaborei Requisitos a serem considerados para o tratamento de erros do Go 2 com um menu de possibilidades para uma eventual solução.
fonte
A maioria na indústria segue as regras padrão mencionadas na documentação do golang Tratamento de erros e Go . E também ajuda na geração de documentos para o projeto.
fonte
Abaixo está minha opinião sobre como reduzir o tratamento de erros no Go, um exemplo é para obter parâmetros de URL HTTP:
(Padrão de design derivado de https://blog.golang.org/errors-are-values )
chamá-lo para vários parâmetros possíveis seria o seguinte:
Isso não é uma solução mágica; a desvantagem é que, se você teve vários erros, só poderá obter o último erro.
Mas, neste caso, é relativamente repetitivo e de baixo risco, portanto, posso obter apenas o último erro possível.
fonte
Você pode limpar seu código de tratamento de erros para erros semelhantes (uma vez que os erros são valores, você deve ter cuidado aqui) e escrever uma função que você chama com o erro passado para tratar o erro. Você não terá que escrever "if err! = Nil {}" toda vez. Novamente, isso só resultará na limpeza do código, mas não acho que seja a maneira idiomática de fazer as coisas.
Novamente, só porque você pode , não significa que você deve .
fonte
goerr permite lidar com erros com funções
fonte
Se você quer um controle preciso dos erros, essa pode não ser a solução, mas para mim, na maioria das vezes, qualquer erro é um obstáculo.
Então, eu uso funções.
fonte
stderr
vez destdout
, então use apenaslog.Fatal(err)
oulog.Fatalln("some message:", err)
. Uma vez que quase nada além demain
tomar essa decisão de encerrar todo o programa (ou seja, retornar erros de funções / métodos, não abortar), no caso raro, isso é o que você deseja fazer, é mais limpo e melhor fazê-lo explicitamente (ou seja,if err := someFunc(); err != nil { log.Fatal(err) }
) em vez de uma função "auxiliar" que não está clara sobre o que está fazendo (o nome "Err" não é bom, não dá nenhuma indicação de que pode encerrar o programa).