Try/Catch é PÉSSIMO (e como consertar)

preview_player
Показать описание

Рекомендации по теме
Комментарии
Автор

Try..catch não é anti-pattern tampouco prejudica a legibilidade do código.
Mascarar erros é anti-pattern. Usar try..catch em todo lugar é anti-pattern.
E se vc pensar em usar try..catch prá escapar de loop, pede as contas agora mesmo.
Erros tem que "borbulhar" na stack para serem tratados nos lugares certos. E try..catch é algo a ser usado com moderação, na hora certa, com o propósito certo. Assim como absolutamente tudo na programação, é mais uma ferramenta, não deve ser demonizado só porque tem mané que usa do jeito errado.
Sem falar que as alternativas são piores. Por exemplo, o "tratamento" de erros do Golang é lindo quando você tem um programinha bem pequeno, com pouca coisa que pode dar errado.
Mas quando a coisa toma corpo e vc tem que lidar com um enorme número de situações imprevisíveis, com tratamento de erros complexos, tratamentos diferentes para erros diferentes... aí meu amigo... você vai ter mais if(err) { ... } do que código de fato. E a legibilidade vai de vasco, fica péssimo de acompanhar até debugando. Experiência própria.

fabioalvescorrea
Автор

Então o problema não é try catch, por que ele tá por baixo dos panos pra poder retornar o error, mas sim não definir o tipo correto de retorno.

seunicolau
Автор

Pra quem quiser outras abordagens para evitar o uso de try catchs, recomendo pesquisarem e estudarem sobre Either Monads. É muito fácil de implementar e depois que você começa a de fato usar, não quer mais abandonar. Sugeri a utilização dele para a minha equipe e acabou se tornando um padrão em nossos projetos. Recomendo muito!

LucasOliveira-tquq
Автор

Toda provocação é válida quando o objetivo é evoluir. Mas sendo bem sincero, houve algus equívocos mais relacionados ao entendimento dos padrões da linguagem do que com o try/catch em si.
Desde aninhamentos de try/catches sem um controle de escopo adequado, confusão com tipagem (python tem tipagem forte e dinâmica, inclusive) ou mesmo try/catch só mascarando erro ao invés de tratá-lo.

Comparar alguns recursos de uma linguagem compilada com uma linguagem interpretada é como comparar laranjas e maçãs. Dá pra discutir trade-offs e usar isso pra melhorias na linguagem (tipo o type hint do python ou o typescript, meio que feitos para se aproximar de tipagem estática que você elogiou, por exemplo), mas usar uma amostra de código dificulta a discussão e não ajuda a entender o todo.
Não subestime a capacidade de um dev cansado de fazer caquinha em Go também.

alexandreabto
Автор

O artigo muito taxativo e bom pra pegar dev junior que gosta de hype. Mais um artigo no Medium que busca polemizar. O autor apresenta exemplos baseados em TypeScript. Nesses tipos de linguagem, devido a liberdade da fazer como você quiser, cabe ao programador tomar os seus devidos cuidados. Esse artigo, assim como video, só leva em consideração o mundo da sua linguagem e esse é um detalhe muito importante. Tenta fazer uma requisição web no Java pra ver se ele não te obrigar a usar um try-catch ou um throws na assinatura do método caso o caller vá tratar a exceção. Tem linguagem que não tem pra onde correr. E isso bom na minha opinião. Deixa na mão de um cara iniciante sem supervisão a decisão de como tratar a exceção, logo logo você vai ver o cara fazendo uma requisição sem tratamento de erro ou try catch, ai na primeira coisinha pipoca tudo.

TheFelipegustavo
Автор

Discordo. Quem deve tratar os erros é o chamador de nível superior, e não a cadeia de chamadas.
Os erros previsíveis que sejam validados via estrutura condicional e borbulhados para cima utilizando throw.
Os erros não previsíveis basta deixar as Exception borbulharem naturalmente para cima e lá realizar o tratamento.

lobohacker
Автор

"raios gamas podem flipar bits" mano imagina o azar do cara investigando bug por isso

alexmarchand
Автор

Bom, Java tem um handler que me agrada muito. Me ajuda demais.

Além de haver um handler (try...catch), temos a cláusula throws, que pode ser fornecida a métodos para informar a chamadas que aquele método pode lançar determinada exceção.
A cláusula " throws" é seguida de uma exceção que podemos lançar. O compilador reclama muito quando não tratamos ela no chamador do método, e nem conseguimos rodar a aplicação.

Além disso, temos a cláusula " throw", onde podemos decidir lançar uma nova exceção de dentro do método ou de dentro do catch, onde podemos relançar nossa exceção ao nível superior, caso não tenha como nos recuperar de um erro no método.

Java nos permite definir vários catchs para um único try, ou então usar um padrão multicatch, onde apenas uma catch pode pegar várias exceções.

E o recurso mais legal que amo no java é o try-with-resources, que elimina a necessidade de escrevermos blocos finally para limpar recursos.
Claro que nada nos impede de escrever catchs ou finallys em try-with-resources, ele apenas tira essa preocupação.

Eu acho que java é extremamente robusto. Me serve e muito pra muita coisa e me ajuda demais com essas operações críticas.
Eu trabalho com desenvolvimento de softwares de gestao administrativa e tipo, não posso ter falhas. Então Java me ajuda muito nesse lado. Fora os recursos e o desempenho da linguagem que faz os olhos brilharem 🥹

Aprendam Java, é magnífico!

RenascenceOfficial
Автор

9:56 - Trabalha cansado, com 3h de sono, fumando 9 prensados por dia, participando de 5 reuniões por dia, foda

pedroAWEJNFO
Автор

Galego, acho que você errou no comentário sobre o finally do inner_method. É impossível aquela função retornar None, o return type dela pode ser corretamente declarado como int.

O finally não tem um return None implicito. Quando o ZeroDivisionError for levantado, ele vai ignorar o except ValueError, pois não é um ValueError, e como não tem mais nenhum except, a exceção vai subir na call stack, porém antes de subir, o finally tem que ser executado. Após o finally ser executado, o erro é re-levantado, sem retornar o None. None nunca é retornado aqui.

A não ser que você coloque um return None no finally, mas ai sua função sempre vai retornar None, independente de ter uma exception no try ou não.

baconlife
Автор

Resumindo, o problema não é o try/catch, mas sim o Dev ruim em estrutura de dados.

seoky
Автор

Fico feliz de saber que eu já usava o throw só pra ir lancanço o erro pra cima e o try catch apenas na camada de apresentação pra poder saber e localizar o que tinha acontecido

jeanfraga
Автор

5:14, A velha pegadinha do strongly typed x dynamically typed. Python é FORTEMENTE e DINAMICAMENTE tipado.
Sobre a forma de uso de try/catch isso é uma daquelas coisas que… depende dos cenários (como quase tudo em nossa área). Eu penso o contrário, exceptions não deveriam ser prioritariamente tratadas in-local (exceto se há uma boa razão para isso), até pelo fato de algumas vezes não fazer sentido (out of memory). Na maioria das vezes é melhor deixar propagar e deixar a camada mais acima tratar e lidar com esses erros, talvez tenha algum mecanismo ESPECIALIZADO na camada que trate os cenários de erros. Tentar tratar a maioria ou todas as exceptions no local onde elas ocorrem leva àquele local a ter mais ruído/sujeira de código, aumenta a complexidade, pois em alguns casos no tratamento haverá logging envolvido ou algum mecanismo de tracing e, consequentemente, importação de módulos e código que proveja essas funcionalidades causando aumento do grafo de DEPENDÊNCIAS não essenciais para aquela rotina. Além do ruído e distração causada, há também impacto no refactoring futuro devido às dependências. Propagando para cima é muito mais legível e possibilita uma estratégia muito mais modular e organizada/especializada. Um exemplo bem legal disso é o Django Rest Framework que nas classes de View tem um método onde você registra um manipulador especializado para tratar as exceptions que ocorrem nas chamadas daquele View set (pena que várias pessoas desconhecem).
Quanto a forma que o Golang faz… well… sendo um programador de Go também, eu diria que há melhores formas de tratar erros. No final do dia, algumas dessas coisas depende muito da visão de cada sobre design.
Desculpa o textão e bom vídeo! ;)


P.S.: goto sendo considerado ruim não é consenso. Há cenários onde faz muito sentido do ponto de vista pragmático. Mas eu mesmo não uso (falando em C)

ailuros_
Автор

putz. assisti o video todo para descobrir que já é do jeito que eu programo.
uso um try catch só nas controller e fazendo ali o tratamento de erro pra retornar ao usuario, e na camada de services fazendo a validação, tratamento, e requisição dos dados e avisando seus respectivos erros com throw error

justrelax
Автор

Interessante acompanhar esse assunto. Sou programador Cobol e realmente, GO-TO é uma grande merda que a gente tinha que lidar lá atrás e era muito chato para debugar. Por esse tipo de problemas criou-se uma convenção de não usarmos go-to, ever!

E o mais interessante desse vídeo, é que o "como consertar" é exatamente como fazemos no Cobol, para ficar mais legível e evitar bugs.

Engraçado que algo que já faziam décadas atrás, estão sugerindo e implementando atualmente(result pattern)... O universo do software é realmente em ciclos né...

Aliás, parabéns pelo ótimo conteúdo como sempre Galego!

Set_Abominae
Автор

Mano, já acompanho seus vídeos tem um tempo, e tem me ajudado bastante seus conteúdos. Além da didática, a maneira da exposição dos tópicos é ótima!

matheusbarreto
Автор

5:14 Python tem tipagem forte e dinâmica

gabrielcastro
Автор

Muito bom vídeo, foi uma das coisas que mais gostei em Go quando comecei a alguns anos atrás, é o fato do error não ser um objeto concreto na linguagem, podendo interagir com o tipo dele de forma mais livre, mas ainda assim existe uma espécie de "try/catch" em go. Mesmo em funções que não retornam erros diretamente, existe uma possibilidade de uma exception ocorrer. Se forem funções de pacotes padrões do Go provavelmente o motivo é que parte do processo dessa função está acontecendo fora do escopo em que o runtimer do go pode vistoriar ou acessar, ou se for um pacote criado por você ou pela comunidade, pode ocorrer se a função "panic" for chamada. Basicamente ela é para funcionar de forma similar as outras linguagens, mas no momento em que a exception quebra a pilha e encerra o programa, ela basicamente recebe um any e vai quebrar a pilha de execução inteira e retornar o que ela recebeu como exception, mesmo que nem seja uma, inclusive. Caso esse panic ocorra, vc pode usar o defer juntamente com a função recover para poder fazer algo em cima desse erro que gerou o panic. Eu particularmente acho essa parada de Panic/Recover meio dúbio, mas entendo a necessidade dela na linguagem. De qualquer maneira, a forma padrão de se lidar com erros em Go é como descreveu, e realmente evita bastante esse problemas de Try/Catch.

dhanielr
Автор

Pior do que usar try catch é não usar. Tem programador que se preocupa tanto com a qualidade do código que entrega que até esquece do software que está fazendo.

KodornaRocks
Автор

Me tira uma duvida boba mais pra mim e importante (ela vai na contra mao do video com seu raciocionio)
1 - Try-catch sem throw: Se você não usar throw dentro do bloco catch, o erro é capturado e tratado ali mesmo? Se sim o programa continua a execução normalmente após o bloco catch ?

2 - Throw dentro do catch: Se você usar throw dentro do bloco catch, a exceção é lançada novamente e propagada para outros blocos catch mais acima na pilha de chamadas, até que seja capturada novamente ou até que não haja mais blocos try-catch ?

3 - A exceção lançada com throw continuará subindo na pilha de chamadas até encontrar um bloco try-catch que a capture ? Se ele não encontrar, será tratada como uma exceção não capturada e pode terminar a execução do programa chegando ate o main?

vitorbrussolo