🐹 Aula 47 – Tutorial Golang – Uso do Recover no Controle de Fluxo

🐹 Aula 47 – Tutorial Golang – Uso do Recover no Controle de Fluxo

Tutorial Golang

Tutorial Golang

Página principal do blog

Todas as aulas desse curso

Aula 46                                Aula 48

Redes Sociais do Código Fluente:

facebook

 

 


Scarlett Finch

Scarlett Finch é uma influenciadora virtual criada com IA.

Ela é 🎤 cantora e 🎶compositora pop britânica , 20 anos e poucos de idade.

Siga a Scarlett Finch no Instagram:

facebook

 


Conecte-se comigo!

LinkedIn: Fique à vontade para me adicionar no LinkedIn.

Ao conectar-se comigo, você terá acesso a atualizações regulares sobre desenvolvimento web, insights profissionais e oportunidades de networking no setor de tecnologia.

GitHub: Siga-me no GitHub para ficar por dentro dos meus projetos mais recentes, colaborar em código aberto ou simplesmente explorar os repositórios que eu contribuo, o que pode ajudar você a aprender mais sobre programação e desenvolvimento de software.

Recursos e Afiliados

Explorando os recursos abaixo, você ajuda a apoiar nosso site.

Somos parceiros afiliados das seguintes plataformas:

  • https://heygen.com/ – Eleve a produção de seus vídeos com HeyGen! Com esta plataforma inovadora, você pode criar vídeos envolventes utilizando avatares personalizados, ideal para quem busca impactar e conectar com audiências em todo o mundo. HeyGen transforma a maneira como você cria conteúdo, oferecendo ferramentas fáceis de usar para produzir vídeos educativos, demonstrações de produtos e muito mais. Descubra o poder de comunicar através de avatares interativos e traga uma nova dimensão para seus projetos. Experimente HeyGen agora e revolucione sua forma de criar vídeos!
  • letsrecast.ai – Redefina a maneira como você consome artigos com Recast. Esta plataforma transforma artigos longos em diálogos de áudio que são informativos, divertidos e fáceis de entender. Ideal para quem está sempre em movimento ou busca uma forma mais conveniente de se manter informado. Experimente Recast agora.
  • dupdub.com – Explore o universo do marketing digital com DupDub. Esta plataforma oferece ferramentas inovadoras e soluções personalizadas para elevar a sua estratégia de marketing online. Ideal para empresas que buscam aumentar sua visibilidade e eficiência em campanhas digitais. Descubra mais sobre DupDub.
  • DeepBrain AI Studios – Revolucione a criação de conteúdo com a tecnologia de inteligência artificial da DeepBrain AI Studios. Esta plataforma avançada permite que você crie vídeos interativos e apresentações utilizando avatares digitais gerados por IA, que podem simular conversas reais e interações humanas. Perfeito para educadores, criadores de conteúdo e empresas que querem inovar em suas comunicações digitais. Explore DeepBrain AI Studios.
  • Audyo.ai – Transforme a maneira como você interage com conteúdo auditivo com Audyo.ai. Esta plataforma inovadora utiliza inteligência artificial para criar experiências de áudio personalizadas, melhorando a acessibilidade e a compreensão de informações através de podcasts, transcrições automáticas e síntese de voz avançada. Ideal para profissionais de mídia, educadores e qualquer pessoa que deseje acessar informações auditivas de maneira mais eficiente e envolvente. Descubra Audyo.ai e suas possibilidades.
  • Acoust.io – Transforme sua produção de áudio com Acoust.io. Esta plataforma inovadora fornece uma suite completa de ferramentas para criação, edição e distribuição de áudio, ideal para artistas, produtores e empresas de mídia em busca de excelência e inovação sonora. Acoust.io simplifica o processo de levar suas ideias à realidade, oferecendo soluções de alta qualidade que elevam seus projetos de áudio. Experimente Acoust.io agora e descubra um novo patamar de possibilidades para seu conteúdo sonoro.
  • Hostinger – Hospedagem web acessível e confiável. Ideal para quem busca soluções de hospedagem de sites com excelente custo-benefício e suporte ao cliente robusto. Saiba mais sobre a Hostinger.
  • Digital Ocean – Infraestrutura de nuvem para desenvolvedores. Oferece uma plataforma de nuvem confiável e escalável projetada especificamente para desenvolvedores que precisam de servidores virtuais, armazenamento e networking. Explore a Digital Ocean.
  • One.com – Soluções simples e poderosas para o seu site. Uma escolha ideal para quem busca registrar domínios, hospedar sites ou criar presença online com facilidade e eficiência. Visite One.com.

Educação e Networking

Amplie suas habilidades e sua rede participando de cursos gratuitos e comunidades de desenvolvedores:

Canais do Youtube

Explore nossos canais no YouTube para uma variedade de conteúdos educativos e de entretenimento, cada um com um foco único para enriquecer sua experiência de aprendizado e lazer.

Toti

Toti: Meu canal pessoal, onde posto clips artesanais de músicas que curto tocar, dicas de teoria musical, entre outras coisas.

Lofi Music Zone Beats

Lofi Music Zone Beats: O melhor da música Lofi para estudo, trabalho e relaxamento, criando o ambiente perfeito para sua concentração.

Backing Track / Play-Along

Backing Track / Play-Along: Acompanhe faixas instrumentais para prática musical, ideal para músicos que desejam aprimorar suas habilidades.

Código Fluente

Código Fluente: Aulas gratuitas de programação, devops, IA, entre outras coisas.

Putz!

Putz!: Canal da banda Putz!, uma banda virtual, criada durante a pandemia com mais 3 amigos, Fábio, Tatá e Lula.

Scarlett Finch

Scarlett Finch: Cantora e influenciadora criada com IA.

PIX para doações

PIX Nubank

PIX Nubank


🐹 Aula 47 – Tutorial Golang – Uso do Recover no Controle de Fluxo

Introdução

No Go, o panic indica um estado de erro crítico que interrompe a execução normal do programa. No entanto, às vezes pode ser desejável tentar “resgatar” (recuperar) o fluxo do programa após um panic, permitindo uma finalização mais tranquila e controlada. E é aí que entra o recover.

O recover() é uma função built-in em Go, capaz de capturar um panic e evitar que o programa termine abruptamente.

Para funcionar, o recover precisa ser chamado dentro de um defer e na mesma função (ou em funções chamadas pela função) onde o panic pode ocorrer. Caso contrário, ele não consegue capturar o erro.

Na aula anterior, vimos o uso de defer e como ele é executado ao final da função. Hoje, vamos explorar como combinar defer + recover para lidar com situações em que queremos retomar o controle após um panic.


1. Exemplo Simples (Retirado do Go By Example)

Este exemplo é direto e ilustra o funcionamento do recover com o uso de panic.

46 – recover/basic_recover.go

package main

import "fmt"

func mayPanic() {
    panic("a problem")
}

func main() {
    defer func() {
        // recover() só funciona dentro de uma função defirada
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()

    mayPanic()

    // Essa linha não será executada, pois a execução retoma no defer acima
    fmt.Println("Depois de mayPanic()")
}

Como funciona:

  • mayPanic() dispara um panic simples.
  • A função anônima (a que tem o defer) verifica se há um panic em andamento usando recover().
  • Se recover() capturar um valor diferente de nil, significa que houve um panic, então o programa exibe a mensagem de erro e continua a execução.

Resultado esperado ao rodar:

Recovered. Error:
 a problem

Note que a linha fmt.Println("Depois de mayPanic()") não é executada porque o fluxo é retomado dentro do defer e não volta para a linha seguinte de mayPanic().


2. Exemplo Prático de Recover em Funções Aninhadas

Imagine que você tem um conjunto de funções em cadeia, e uma delas pode disparar um panic. Podemos encapsular o recover() em um local central para capturar qualquer falha que ocorra nas funções chamadas.

47 – recover/nested-functions/nested_recover.go

package main

import (
    "fmt"
)

func operacaoCritica() {
    // Simula uma condição de erro
    panic("Erro crítico na operação!")
}

func funcaoIntermediaria() {
    // Chama a função que pode gerar um panic
    operacaoCritica()
}

func ExecutarOperacaoComSeguranca() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recuperado na função ExecutarOperacaoComSeguranca:", r)
        }
    }()
    // Chama uma função intermediária que por sua vez chama operacaoCritica()
    funcaoIntermediaria()
    fmt.Println("Operação intermediária concluída com sucesso!")
}

func main() {
    fmt.Println("Iniciando main...")

    ExecutarOperacaoComSeguranca()

    fmt.Println("Finalizando main!")
}

Explicação:

  • operacaoCritica() dispara um panic sempre que for chamada (simulando uma falha crítica).
  • funcaoIntermediaria() é apenas um “meio de campo” que chama a operação crítica.
  • ExecutarOperacaoComSeguranca() utiliza defer e recover() para capturar o panic gerado pela operacaoCritica().
  • Ao rodar este código, você verá a mensagem de erro sendo capturada e o fluxo continua após o recover.

Saída esperada:

Iniciando main...
Recuperado na função ExecutarOperacaoComSeguranca: Erro crítico na operação!
Finalizando main!

Note que a linha fmt.Println("Operação intermediária concluída com sucesso!") não será exibida, pois o fluxo é interrompido no panic, e só é retomado dentro do defer, não voltando para o ponto após funcaoIntermediaria().


3. Exemplo com HTTP Server

Uma situação bastante comum é querermos evitar que uma única requisição com erro “derrube” todo o servidor. Por exemplo, o pacote net/http internamente utiliza algo similar a recover() para lidar com panics em handlers.

47 – recover/http-server/http_recover.go

package main

import (
    "fmt"
    "log"
    "net/http"
)

// middlewareRecover é um middleware que encapsula um Handler com recover
func middlewareRecover(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                // Capturando o panic e evitando que o servidor pare
                http.Error(w, "Ocorreu um erro interno.", http.StatusInternalServerError)
                log.Printf("Panic capturado: %v", err)
            }
        }()
        next.ServeHTTP(w, r)
    })
}

func handlerPanic(w http.ResponseWriter, r *http.Request) {
    // Forçando um panic
    panic("Falha crítica ao processar a requisição!")
}

func handlerOK(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Esta rota funciona normalmente.")
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/panic", handlerPanic)
    mux.HandleFunc("/ok", handlerOK)

    // Aplicando nosso middleware de recover
    srv := &http.Server{
        Addr:    ":8080",
        Handler: middlewareRecover(mux),
    }

    fmt.Println("Servidor iniciado na porta 8080")
    log.Fatal(srv.ListenAndServe())
}

Como funciona:

  • middlewareRecover é uma função que recebe um http.Handler e retorna outro http.Handler, mas encapsulado em um defer para capturar possíveis panics.
  • Se algum panic ocorrer em qualquer rota, ele é capturado pelo recover() e é retornado um HTTP 500 (erro interno).
  • Desta forma, seu servidor continua rodando normalmente, apesar do erro local.

Testando:

  • Acesse http://localhost:8080/ok e veja a mensagem “Esta rota funciona normalmente.”
  • Acesse http://localhost:8080/panic e note que, mesmo forçando um panic, o servidor retorna 500 em vez de simplesmente “quebrar”.

4. Exemplo de Recuperação em Goroutines

Um panic em uma goroutine específica não encerra diretamente o programa (a não ser que seja a goroutine principal). Mas, se quisermos capturar o panic em cada goroutine, podemos aplicar a mesma lógica de recover internamente.

47 – recover/goroutines/recover_goroutines.go

package main

import (
    "fmt"
    "sync"
    "time"
)

func executarTarefa(id int, wg *sync.WaitGroup) {
    defer func() {
        // Captura qualquer panic da goroutine
        if r := recover(); r != nil {
            fmt.Printf("[Goroutine %d] Recuperado do panic: %v\n", id, r)
        }
        wg.Done()
    }()

    // Simulando condição de erro em goroutine par
    if id%2 == 0 {
        panic(fmt.Sprintf("Algo deu errado na goroutine %d", id))
    }

    // Simulação de trabalho
    time.Sleep(time.Duration(id) * 100 * time.Millisecond)
    fmt.Printf("[Goroutine %d] Tarefa concluída com sucesso!\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go executarTarefa(i, &wg)
    }

    wg.Wait()
    fmt.Println("Todas as goroutines finalizaram (com ou sem erro)!")
}

Explicação:

  • A função executarTarefa defera(adia) um bloco que chama recover(). Se ocorrer um panic, ele será capturado dentro da goroutine.
  • No exemplo, forçamos um panic em goroutines com id par, simulando algum erro específico.
  • Assim, cada goroutine pode continuar (ou, no mínimo, tratar o erro de forma controlada), sem encerrar o programa inteiro.

Saída esperada (a ordem pode variar, pois o scheduler de goroutines não é determinístico):

[Goroutine 2] Recuperado do panic: Algo deu errado na goroutine 2
[Goroutine 1] Tarefa concluída com sucesso!
[Goroutine 4] Recuperado do panic: Algo deu errado na goroutine 4
[Goroutine 3] Tarefa concluída com sucesso!
[Goroutine 5] Tarefa concluída com sucesso!
Todas as goroutines finalizaram (com ou sem erro)!

Obs. A ordem pode ser diferente dessa saída acima, isso é absolutamente normal. Quando se trata de goroutines, a ordem de execução delas não é garantida. Cada goroutine é escalonada de maneira independente e assíncrona pelo runtime do Go, então, o momento exato em que cada goroutine imprime suas mensagens pode variar de uma execução para outra.

Conclusão

Nesta aula, vimos como recover trabalha em conjunto com defer para capturar panics e evitar que o programa seja encerrado abruptamente. Em muitos casos, essa abordagem é preferível a deixar o aplicativo “cair”, especialmente quando é possível isolar e tratar o erro localmente.

O uso de recover deve ser criterioso. Nem sempre é desejável capturar todos os panics, pois isso pode mascarar problemas graves que deveriam encerrar o programa. Entretanto, em situações como servidores HTTP, goroutines e bibliotecas que não podem parar a aplicação por inteiro, recover se torna uma ferramenta valiosa para manter a robustez do sistema.

Na próxima aula, vamos explorar String Functions em Go.

Focaremos em diversas funções nativas para manipulação de strings, tornando nosso desenvolvimento em Go ainda mais eficiente.

Até a próxima aula!

About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>