Categorias do Site

Como usar try…catch em JavaScript

Aprenda a usar try...catch em JavaScript para lidar com erros e melhorar a experiência do usuário.

Um círculo amarelo com

Construir aplicações JavaScript envolve antecipar e lidar com problemas inesperados. Os erros são inevitáveis, mas gerenciá-los efetivamente garante uma melhor experiência do usuário. O JavaScript oferece o bloco try…catch como uma maneira estruturada de lidar com erros de forma elegante.

Como Usar Try...catch Para Tratamento de Erros em JavaScript

Este artigo explora como usar o bloco try…catch, abordando sua sintaxe básica e cenários avançados, como blocos aninhados, lançamento de erros e tratamento de código assíncrono.

A sintaxe básica de try...catch

A instrução try...catch consiste em três partes principais:

  • Um bloco try — Contém o código que pode gerar um erro
  • Um bloco catch — Lida com um erro se ocorrer. É executado apenas quando um erro é gerado
  • Um bloco finally — Executa o código de limpeza. Ele é executado independentemente de um erro ser gerado ou não

O bloco try deve ser seguido por um bloco catch ou finally, ou ambos, como mostrado abaixo:

    // try...catch
    try{
    console.log("executando bloco try...")
    console.log(missingVar)
    }catch{
    console.log("ocorreu um erro")
    }
    
    // SAÍDA:
    // executando bloco try...
    // ocorreu um erro


    // try...finally
    try{
    console.log("executando bloco try...")
    }finally{
    console.log("declaração final")
    }
    
    // SAÍDA:
    // executando bloco try...
    // declaração final


    // try...catch...finally
    try{
    console.log("executando bloco try...")
    console.log(missingVar)
    }catch(errorVar){
    console.log("ocorreu um erro",errorVar)
    }finally{
    console.log("declaração final")
    }
    
    // SAÍDA:
    // executando bloco try...
    // ocorreu um erro
    // declaração final

O bloco catch possui um identificador de erro que pode ser usado para acessar o erro gerado. Você pode acessá-lo como um todo (por exemplo, errorVar) ou usar suas propriedades individualmente:

  • errorVar.name – Especifica o tipo de erro
  • errorVar.message – Fornece uma descrição do erro legível para humanos

O trecho de código abaixo usa desestruturação para acessar o erro gerado:

    try {
        console.log(missingVar)
    } catch ({name, message}) {
        console.log("nome: ", name)
        console.log("mensagem: ", message)
    }
    
    // SAÍDA:
    // nome:  ReferenceError
    // mensagem:  missingVar não está definida

Lançando erros personalizados

Às vezes, erros embutidos como TypeError não capturam completamente o que deu errado. Lançar erros personalizados permite fornecer mensagens de erro mais claras e incluir informações adicionais para depuração.

Para criar um erro personalizado, você estende a classe Error, define um construtor que define uma mensagem de erro significativa e atribui um nome personalizado. Você pode opcionalmente incluir informações adicionais de depuração e capturar o rastreamento de pilha original para depuração no desenvolvimento:

class OperationError extends Error {
/**
* Erro personalizado para lidar com falhas de operação.
* @param {string} resource - O recurso envolvido no erro.
* @param {string} action - A ação que falhou.
*/
constructor(resource, action) {
// Construa uma mensagem de erro significativa
super(`Falha ao ${action} ${resource}. Verifique o recurso e tente novamente.`);
// Preserve o rastreamento de pilha original (opcional, útil para depuração)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, OperationError);
}
this.name = "OperationError";
// Informações de depuração personalizadas
this.resource = resource;
this.action = action;
}
}

No trecho de código abaixo, o erro personalizado é lançado no bloco try para simular uma chamada de função que pode encontrar esse tipo específico de erro. O objeto de erro inclui o rastreamento de pilha e propriedades adicionais de erro:

    
try {
    // simular uma operação que pode lançar uma exceção
      throw new OperationError("arquivo", "ler");
    } catch (error) {
      console.error(`${error.name}: ${error.message}`);
    
      console.log(`informações adicionais: o recurso era um ${error.resource} e a ação era ${error.action}`)
    
      console.log(error)
    }
    
    // SAÍDA:
    // OperationError: Falha ao ler o arquivo. Verifique o recurso e tente novamente.
    
    // informações adicionais: o recurso era um arquivo e a ação era ler
    
    // OperationError: Falha ao ler o arquivo. Verifique o recurso e tente novamente.
    //     at Object.< anonymous > (/Users/walobwa / Desktop /project / test.js: 25: 11)
    //     at Module._compile(node: internal / modules / cjs / loader: 1376: 14)
    //     at Module._extensions..js(node: internal / modules / cjs / loader: 1435: 10)
    //     at Module.load(node: internal / modules / cjs / loader: 1207: 32)
    //     at Module._load(node: internal / modules / cjs / loader: 1023: 12)
    //     at Function.executeUserEntryPoint[as runMain](node: internal/modules/run_main: 135: 12)
    //     at node: internal / main / run_main_module: 28: 49 {
    //     resource: 'arquivo',
    //         action: 'ler'
    // }

Blocos catch condicionais

Blocos catch condicionais usam a instrução if...else para lidar com erros específicos, permitindo que os inesperados sejam propagados.

Conhecer os diferentes tipos de erros que podem ser lançados ao executar o código ajuda a lidar com eles adequadamente. Usando instanceof, podemos capturar erros específicos como OperationError e fornecer uma mensagem significativa para o erro:

    try {
    // simular uma operação que pode lançar uma exceção
        throw new OperationError("arquivo", "ler"); 
    } catch (error) {
        if (error instanceof OperationError) {
    // lidar com erro esperado
            console.error("Erro de Operação encontrado:", error.message);
        } else {
    // registrar erro inesperado
            console.error("Erro inesperado encontrado:", error.message);
        }
    }
    // SAÍDA:
    // Erro de Operação encontrado: Falha ao ler o arquivo. Verifique o recurso e tente novamente.

No trecho de código acima, registramos qualquer outro erro na instrução else. Uma boa prática seria relançar erros não explicitamente tratados no bloco try...catch.

Relançando erros

Relançar erros garante que eles sejam propagados para cima na pilha de chamadas para tratamento. Isso evita falhas silenciosas e mantém o rastreamento de pilha.

No trecho de código abaixo, capturamos o erro esperado, OperationError, silenciamos e, em seguida, adiamos o tratamento de outros erros relançando-os. A função de nível superior agora lidará com o erro relançado:

    try {
        throw new TypeError("X não é uma função"); 
    } catch (error) {
        if (error instanceof OperationError) {
            console.error("Erro de Operação encontrado:", error.message);
        } else {
        throw error; // relançar o erro inalterado
        }
    }

Bloco try…catch aninhado

Um bloco try...catch aninhado é usado quando uma operação dentro de um bloco try requer tratamento de erro separado. Ele ajuda a gerenciar várias falhas independentes, garantindo que uma falha não interrompa todo o fluxo de execução.

Erros no bloco interno são capturados e tratados localmente enquanto o bloco externo gerencia erros não tratados ou propagados. Se o erro gerado for tratado no bloco interno try..catch, o bloco catch externo não é executado:

    try {
        try {
            throw new OperationError("arquivo", "ler");
        } catch (e) {
            if (e instanceof OperationError) {
                console.error("Erro de Operação encontrado:", e.message);
            } else {
                throw e; // relançar o erro inalterado
            }
        } finally {
            console.log("bloco finalmente interno");
        }
    } catch (err) {
        console.error("registro de erro externo", err.message);
    }
    // SAÍDA:
    // Erro de Operação encontrado: Falha ao ler o arquivo. Verifique o recurso e tente novamente.
    // bloco finalmente interno

Se um erro não for tratado ou for relançado no bloco interno, o bloco try...catch externo o captura. O bloco finally aninhado é executado antes do bloco catch ou finally externo, garantindo a limpeza em cada nível:

    try {
        try {
            throw new TypeError("arquivo");
        } catch (e) {
            if(e instanceof OperationError) {
                console.error("Erro de Operação encontrado:", e.message);
            } else {
                throw e; // relançar o erro inalterado
            }
        } finally {
            console.log("bloco finalmente interno");
        }
    } catch (err) {
        console.error("registro de erro externo", err.message);
    }
    // SAÍDA:
    // bloco finalmente interno
    // registro de erro externo arquivo

Lidando com erros assíncronos

try...catch funciona com código síncrono. Quando um erro ocorre dentro de uma função assíncrona, o bloco try...catch conclui a execução antes que o erro ocorra, deixando-o não tratado.

Operações assíncronas requerem tratamento de erro adequado para evitar rejeições não tratadas e falhas inesperadas. Usar try...catch com async/await ajuda a evitar que rejeições não tratadas passem despercebidas.

async/await garante que o bloco try…catch espere o resultado da operação assíncrona antes de prosseguir:

    async function openFile(url) {
        try {
            const response = await fetch(url);
            if (!response.ok) {
                throw new OperationError("arquivo", "abrir"); // Reutilizando OperationError para lidar com erros de abertura de arquivo
            }
            return await response.json();
        } catch (error) {
            console.error(`Falha ao buscar arquivo: ${error.message}`);
            // Relançar ou lidar de forma graciosa
            throw error; // Propagar o erro para cima
        }
    }

No exemplo acima, a função openFile é assíncrona. O resultado da operação fetch é aguardado. Se um erro for lançado, ele é registrado e propagado para o bloco try...catch externo onde é tratado:

    try {
        const data = await openFile("data.json");
        console.log(data);
    } catch (error) {
        console.error(`Falha ao abrir arquivo: ${error.message}`);
    }
   

Usando finally para limpeza

O bloco finally em uma instrução try...catch é usado para executar código que deve ser executado independentemente de um erro ocorrer. Isso é útil para operações de limpeza, como fechar arquivos, liberar recursos ou redefinir estados:

    try {
        // operação que abre arquivo e lança erro de operação
        throw new OperationError("arquivo", "ler");
    } catch (error) {
       if(error instanceof OperationError) {
           console.error(`Erro de operação: ${error.message}`);
       } else {
           throw error;
       }
    } finally {
        closeFile(file); // Garante que o arquivo seja fechado mesmo que ocorra um erro
    }

Conclusão

Este tutorial explorou o tratamento de erros em JavaScript usando o bloco try...catch. Abordamos sua sintaxe básica, lançamento de erros personalizados, relançamento de erros e uso de blocos aninhados. Também discutimos o tratamento de erros assíncronos com try...catch e async/await, bem como o uso do bloco finally para limpeza de código.

Ao usar efetivamente try...catch, os desenvolvedores podem construir aplicações mais robustas, prevenir falhas inesperadas e melhorar a depuração, garantindo uma melhor experiência do usuário.

  • O que é Vibe Coding? Descubra essa tendência

    Design com IA evolui para além dos wireframes, focando em 'vibe coding'. Entenda essa nova era do design digital.

    Design com IA evolui para além dos wireframes, focando em 'vibe coding'. Entenda essa nova era do design digital.

    Ler notícia completa
    Banner de podcast com título
  • 20 Fontes Futuristas Gratuitas para Design Moderno

    Descubra 20 fontes futuristas gratuitas para dar um toque moderno e inovador aos seus projetos de design.

    Descubra 20 fontes futuristas gratuitas para dar um toque moderno e inovador aos seus projetos de design.

    Ler notícia completa
    Imagem de fundo cósmico com tonalidades de azul e rosa representando o espaço, contendo a palavra
  • 6 Melhores Plugins de Blocos Gutenberg para WordPress

    Descubra os 6 melhores plugins de blocos Gutenberg para criar páginas incríveis no WordPress.

    Descubra os 6 melhores plugins de blocos Gutenberg para criar páginas incríveis no WordPress.

    Ler notícia completa
    Interface de usuário de um software com um campo de pesquisa e ícones de recursos como
  • Navegação na Internet para Pessoas Cegas

    Sylvie Duchateau é consultora de acessibilidade digital há mais de 20 anos. Após trabalhar em associações como BrailleNet e na cooperativa Access42, ela decidiu se tornar freelancer. Sylvie é especialista em leitores de tela, oferece treinamentos e testes de acessibilidade, e é voluntária na conferência Paris Web desde 2021. Nos conhecemos na edição de 2024 […]

    Sylvie Duchateau fala sobre desafios e soluções para acessibilidade digital de pessoas cegas na web.

    Ler notícia completa
    Mulher sorridente abraça labrador bege em ambiente interno com plantas ao fundo.
  • Guia de Estilo vs. Sistema de Design: Diferenças

    Embora muitos designers usem guias de estilo e sistemas de design de forma intercambiável, eles são ferramentas distintas com suas próprias forças e fraquezas. Compreender suas diferenças é crucial para evitar impactos negativos no processo de design e desenvolvimento de produtos. Um guia de estilo é um documento que apresenta diretrizes para manter a consistência […]

    Entenda as diferenças entre guias de estilo e sistemas de design e como usá-los no design de produtos.

    Ler notícia completa
    Ícone estilizado de um computador exibindo uma imagem de documento com texto e caixas de marcação, acompanhado de um lápis, sobre fundo texturizado azul.
  • AI substituirá PMs? Como proteger sua carreira

    Grupos de PMs em redes sociais frequentemente discutem se a IA substituirá seus empregos. Já é comum ver agentes de IA realizando tarefas básicas de gerenciamento de produtos, como criar roteiros e analisar dados. “Oi ChatGPT, pode criar um roteiro de três meses para meu produto?” “Oi Claude, pode ajudar com perguntas de pesquisa para […]

    Descubra como a IA está impactando os gerentes de produto e como eles podem se adaptar para proteger suas carreiras.

    Ler notícia completa
    Duas chaves inglesas roxas cruzadas sobre um fundo texturizado escuro.
  • Como Criar uma Jornada Moderna do Cliente

    Oren Halperin é Vice-Presidente de Comércio Digital na AJ Madison, uma líder omnichannel em eletrodomésticos. Ele compartilha estratégias para engajar clientes na jornada de compra digital moderna. Em nossa conversa, Oren fala sobre como engajar clientes através de diversos pontos de contato em uma jornada moderna de compra digital. Ele também compartilha práticas recomendadas e […]

    Descubra estratégias eficazes para engajar clientes e aumentar as conversões online em uma jornada digital moderna.

    Ler notícia completa
    Banner azul com círculos roxos e azuis, mostrando Oren Halperin, Vice-Presidente de Comércio Digital na AJ Madison, com logos da LogRocket e AJ Madison.
  • Configurar variáveis de ambiente no Next.js

    Neste artigo, você aprenderá a gerenciar variáveis de ambiente no Next.js usando arquivos .env. Vamos abordar variáveis públicas vs. privadas, hierarquia de arquivos de variáveis de ambiente, limitações de tempo de execução e melhores práticas para configuração segura em desenvolvimento e produção. O que são variáveis de ambiente no Next.js? As variáveis de ambiente no […]

    Aprenda a gerenciar variáveis de ambiente no Next.js, diferenciando públicas e privadas, e suas práticas recomendadas.

    Ler notícia completa
    Ícone circular preto com a letra 'N' branca sobre fundo colorido com tons de azul, verde e roxo, destacado por bolhas luminosas.
  • Dicas para criar testes grátis que convertem

    No passado, os testes gratuitos eram uma tática eficaz para aumentar taxas de conversão e atrair usuários para serviços premium. Oferecer algo de graça era suficiente, mas isso mudou. Hoje, quase todos os produtos de assinatura oferecem um teste gratuito, o que deixou de ser um diferencial competitivo. Testes mal otimizados podem resultar em alta […]

    Aprenda estratégias para otimizar testes gratuitos e aumentar conversões em seus serviços.

    Ler notícia completa
    Ícone de um cartão de presente laranja com laço amarelo dentro de uma moldura roxa, à esquerda de três linhas de texto, sobre fundo azul desfocado.