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.

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.
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 erroerrorVar.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.