---
id: 448c02f1efb1042bc9e1d256fcd2acad
author: Rabbit Princess
title: Por que Go optou pelo retorno explícito de erros e por panic-recover em vez do lançamento de exceções com try-catch
description: Este texto examina as limitações da estrutura try-catch, que transfere a responsabilidade pelo tratamento de exceções ao longo da pilha de chamadas, e descreve o design de panic-recover em Go, restrito a estados irrecuperáveis, em contraste com o tratamento explícito de erros no ponto de chamada.
language: pt
date: 2024-10-16T07:06:25.186989697Z
path: /blog/posts/why-doesn-t-go-have-try-catch-zeb312147
category: language
lang_canonical:
    ko: https://blog.naver.com/sjc02183/222927597790
---

Go deliberadamente não oferece suporte a try-catch e suporta apenas a sintaxe panic-recover. Isso tem gerado insatisfação entre os muitos desenvolvedores acostumados ao tratamento de erros com try-catch. Então, por que o try-catch não foi incluído? Isso ocorre porque o try-catch apresenta vários problemas.

## try-catch-finally

A estrutura try-catch (try-catch) é uma construção destinada a tratar situações de erro e de exceção que podem ocorrer durante a execução do programa (em tempo de execução). Além disso, o bloco finally contém o código que deve ser executado incondicionalmente, independentemente da ocorrência de exceções.

## Tratamento de Erros e Responsabilidade

Nas décadas de 1980 e 1990, o tratamento de erros era muito simples. As mensagens de erro se resumiam a "disquete cheio", "nenhum disquete na unidade" e "sem permissão de gravação no disquete". Nessa época, quando um erro ocorria, os desenvolvedores o propagavam (throw) até o ponto de tratamento de erros, centralizando o processamento. Nesse cenário, a estrutura try-catch funcionava de forma eficiente.

Contudo, com o passar do tempo, a situação mudou. A lógica de negócio tornou-se complexa, surgiram bancos de dados e transações, era preciso chamar inúmeras APIs pela rede e interpretar muitas mensagens de requisição e, até mesmo, com o advento da programação concorrente, tornou-se necessário tratar erros em threads diferentes da principal.

Os erros tornaram-se complexos demais para serem tratados em um único lugar, e nenhum ponto isolado passou a ser capaz de se responsabilizar por todos eles. É aqui que o try-catch passa a apresentar um problema grave.

## A Transferência de Responsabilidade do try-catch

Em suma, o try-catch é um método pelo qual o sujeito que gera um erro transfere a responsabilidade pela sua ocorrência (o tratamento posterior) a outra parte. Essa parte pode ser o bloco catch, o método pai, o pai do pai do pai do pai... ou qualquer outro elemento. Em outras palavras, em um mundo onde o tratamento de erros se torna cada vez mais numeroso e complexo, a solução adotada pelo try-catch é simplesmente "alguém vai resolver". Observe o código abaixo.

```java
try {
    data = readFile("hello.txt");
    structuredData = parseData(data);
    insertDBStatus(structuredData[1]);
    startHTTPServer(structuredData[2]);
} catch (Exception e) {
    e.printStackTrace();
}
```

O problema desse código é que não fica claro qual é o responsável por processar o printStackTrace, e tampouco é possível saber em qual trecho o erro ocorreu. Além disso, quanto mais lógica houver dentro do bloco try, pior a situação se torna. Ainda assim, paradoxalmente, quanto mais complexo o desenvolvimento se tornava, mais os desenvolvedores se viciavam em estruturas try-catch que transferem responsabilidades; deixaram de refletir sobre o tratamento de erros, sua noção de responsabilidade se enfraqueceu e, por fim, esqueceram a essência do tratamento de erros e de exceções. Então, como o Golang resolveu esse problema?

## panic e recover

Uma das vantagens da linguagem Go é possuir diversos mecanismos que, em vez de conduzir o desenvolvedor por caminhos equivocados, o ajudam a se tornar um bom desenvolvedor. O par panic-recover é um exemplo disso.

À primeira vista, panic e recover não parecem diferentes do try-catch, mas diferem no ponto de que, quando ocorre um problema, a responsabilidade não é transferida para o exterior. Em Go, quando ocorre um panic, o valor não é simplesmente repassado para fora; a solução deve ser feita no próprio local onde o panic ocorreu. Isso atribui ao desenvolvedor a responsabilidade pelo tratamento de erros, levando-o a refletir com mais profundidade sobre onde, por quem e como esse erro deve ser tratado. Trata-se de garantir autonomia ao usuário, ao mesmo tempo em que se deixa espaço para a reflexão.

Além disso, a escolha da palavra panic também é notavelmente acertada: diferentemente de try-recover, o par panic-recover impõe ao desenvolvedor a pressão de que deve ser usado apenas em situações de erro evidente, e não em situações meramente excepcionais. Naturalmente, o desenvolvedor não abusa de recover e o utiliza apenas onde é necessário. Isso contribui muito para a escrita de código conciso em Go.
