Saber como gerenciar erros é parte importante da programação. Este tutorial fornece uma introdução fácil ao tratamento de erros em JavaScript. Você aprenderá sobre dois tipos de erros e como lidar com cada um. Você também aprenderá como usar try...catch
e throw
instruções para tornar seu código mais seguro e muito mais.
Dois tipos principais de erros
Quando se trata de manipulação de erros no JavaScript, existem dois tipos de erros que você pode encontrar. O primeiro tipo de erros são erros de sintaxe. O segundo tipo são erros de tempo de execução.
Erros de sintaxe
Erros de sintaxe também são chamados de erros de análise. Isso ocorre quando o analisador JavaScript interpreta seu código. Quando um desses erros ocorre, afeta apenas o código que está no mesmo encadeamento. O restante do código não é afetado. Um exemplo de erro de sintaxe pode ser esquecido ao abrir ou fechar parênteses ou colchete.
Outro exemplo pode estar faltando coma ou dois pontos no objeto. Qualquer um desses erros fará com que a sintaxe seja inválida e interrompa seu programa. Existem algumas maneiras de evitar esses tipos de erros. Um é verificar o seu código e procurá-los. Isso não é eficaz e pode levar muito tempo.
Outra opção é usar alguma ferramenta ou plugin IDE. Essas ferramentas verificarão automaticamente seu código e procurarão por problemas de sintaxe. As três ferramentas mais populares que ajudarão a detectar erros de sintaxe são eslint , jshint e jslint . Eslint é o meu favorito. Eu uso em quase todos os meus projetos.
Essas ferramentas são muito populares e os desenvolvedores não gostam de tarefas repetitivas. Isso torna provável a existência de um plug-in para cada uma dessas ferramentas que você pode instalar no IDE que está usando. Se você encontrar alguns, eu recomendo instalá-lo e usá-lo. Pode poupar muitas dores de cabeça.
Erros de tempo de execução
O segundo tipo de erros são erros de tempo de execução. Esses erros também são chamados de exceções. Esses erros ocorrem durante a execução do seu código, quando você o executa. Um exemplo simples pode ser chamar um método que não existe. Outra pode estar passando a string para uma função em vez do número ou o contrário.
Importante é que cada um desses erros seja válido na visualização do JavaScript. Sim, você pode digitar incorretamente algum nome de variável ou função. No entanto, a própria sintaxe ainda é válida. Não faltam dois pontos ou colchetes. Se isso for verdade, o JavaScript permitirá que seu código seja compilado. Você encontra esses erros apenas quando executa seu código.
É também isso que torna os erros de tempo de execução mais difíceis de lidar. É também por isso que é uma boa idéia escrever e também executar testes de unidade . Além disso, não há plug-in que o ajude a identificar esses erros antes que eles ocorram. Bem, isso é verdade apenas parcialmente. Você pode usar um superconjunto de JavaScript, como o TypeScript .
Se o seu IDE tiver suporte para um desses superconjuntos, ele ajudará a detectar erros de tempo de execução. Por exemplo, quando você usa o TypeScript no código VS, ele avisa quando alguma função ou variável que você deseja usar está indefinida. Também sugerirá métodos e variáveis que você definiu anteriormente enquanto escreve seu código.
Além disso, existem algumas ferramentas internas do JavaScript que facilitarão o tratamento de erros. Vamos dar uma olhada nessas ferramentas.
Tratamento de erros e tentativa… catch
A primeira ferramenta para tratamento de erros é uma try...catch
declaração. Esta declaração pode ser semelhante à if...else
declaração. Ele também contém dois blocos de código, embrulhados com chaves. No entanto, não há parênteses antes do primeiro bloco, o try
bloco. Este try
bloco contém o código que você deseja tentar executar.
try {
// some code
}
Dito isto, todo o seu código não precisa ser definido em um único try
bloco gigante . Em vez disso, você coloca no try
bloco apenas o que deseja executar. Por exemplo, digamos que você queira declarar alguma função . Você pode declarar essa função em algum lugar fora do try
bloco, mas invoca a função dentro dele.
// Declare function outside try block
function myFunction() {
// do something
}
// Create try block
try {
// And invoke the function inside it
myFunction()
}
Pegar
Quando você fizer isso, o try
bloco chamará essa função. Se sua função for executada sem erros, nada acontecerá. Se houver alguns erros de tempo de execução? É aqui que o catch
bloco entra em jogo. O catch
bloco é semelhante a try
. Uma diferença é que existem parênteses após a catch
palavra – chave e antes de abrir a chave.
Dentro desses parênteses está definido um parâmetro. Este parâmetro é um objeto de erro. Este objeto contém informações sobre o erro que ocorreu. Ele contém o nome do erro, a mensagem de erro e a pilha de chamadas atual. O catch
bloco é um local onde você define o que fazer quando ocorrer um erro.
// Create try...catch statement
try {
// Run some code
}
catch(error) { // error is the error object, you can use a different name
// Do something when an error occurs
}
// Example:
// Create try...catch statement
try {
// Try to invoke function that doesn't exist
myFunc()
}
catch(error) {
console.log('Error name: ', error.name)
console.log('Error message: ', error.message)
console.log('Error stack: ', error.stack)
console.log('Error: ', error)
}
// Outputs:
// 'Error name: ' 'ReferenceError'
// 'Error message: ' 'myFunction is not defined'
// 'Error stack: ' `ReferenceError: myFunction is not defined
// at eval (eval at <anonymous> (:7:47), <anonymous>:4:3)
// at <anonymous>:7:47
// at <anonymous>:15:9`
// ...
// 'Error: ' ReferenceError: myFunction is not defined
// at eval (eval at <anonymous> (:7:47), <anonymous>:4:3)
// at <anonymous>:7:47
// at <anonymous>:16:9
// ...
O parêntese e o objeto de erro após a catch
palavra – chave e antes de abrir o colchete são opcionais. É usado para passar as informações sobre erro. Se você não quiser usar essas informações, poderá omitir os dois, o parêntese e o objeto de erro. A try...catch
declaração ainda funcionará.
// Create try...catch statement
try {
// Try to invoke function that doesn't exist
myFunction()
}
catch { // Omit parenthesis and error object
// Show some custom error message
console.log('An error occurred.')
}
// Outputs:
// 'An error occurred.'
Experimente, pegue e controle
O código dentro do catch
bloco é executado imediatamente quando ocorre algum erro de tempo de execução. Isso é importante, lembre-se. Se algum código que você executar no try
bloco levar a um erro, qualquer código a seguir, dentro do mesmo try
bloco, não será executado. O catch
bloco assumirá automaticamente o controle e processará o erro.
// Create function that leads to an error
function myFuncWithError() {
throw 'Error'
}
// Create another function that doesn't lead to an error
function myFunc() {
console.log('Hello.')
}
// Create try...catch statement
try {
// Invoke the myFuncWithError function
// If this function causes error...
myFuncWithError()
// Invoke the myFunc function
// ...this function will never be invoked
myFunc()
}
catch(error) {
// Log any error message
console.log(error)
}
// Outputs:
// 'Error'
// Note:
// Only myFuncWithError() function was invoked
// then control shifted to catch block
// and myFunc() function was never invoked
Usando várias instruções try… catch
Existe uma maneira de corrigir isso. Em JavaScript, não há limite para quantas try...catch
instruções você pode usar. Também não há uma regra que você precise usar uma para todo o seu código. Se alguma coisa, você deve realmente fazer o oposto. O uso de várias try...catch
instruções permite isolar erros e não afetar o restante do seu código.
Se você deseja chamar as duas funções, a coisa mais fácil que você pode fazer é criar duas try...catch
instruções. Em seguida, você pode invocar uma função na primeira instrução e outra função na segunda.
// Create function that leads to an error
function myFuncWithError() {
throw 'Error'
}
// Create another function that doesn't lead to an error
function myFunc() {
console.log('Hello.')
}
// Create first try...catch statement
try {
// Invoke the myFuncWithError function
myFuncWithError()
}
catch(error) {
// Log any error message
console.log(error)
}
// Create second try...catch statement
try {
// Invoke the myFunc function
myFunc()
}
catch(error) {
// Log any error message
console.log(error)
}
// Outputs:
// 'Error'
// 'Hello.'
// Note: both functions were successfully invoked
// because error that occurred in the first
// was caught by the first try...catch statement
// and had no effect on the second function
O exemplo funcionaria com qualquer número de função ou código que você deseja chamar ou executar. Você pode criar dezenas ou mais try...catch
instruções para lidar com um caso de uso específico. Portanto, qualquer erro que ocorra não afetará o restante do seu código, invocado ou executado em outras try...catch
instruções.
Como você pode ver, a try...catch
declaração é uma ferramenta muito poderosa para o tratamento de erros. Ele permite que você execute partes do seu código sem deixá-lo travar em outras partes ou em todo o aplicativo. Dito isto, há mais.
Finalmente
A try...catch
declaração pode ajudá-lo a facilitar o tratamento de erros. No entanto, também há um finally
bloco que você pode usar. O try
chama o código dentro do bloco. O catch
é chamado quando ocorre um erro. O finally
é invocado no final de cada try...catch...finally
instrução.
O importante é que o finally
é invocado em todos os casos. Não importa se há um erro ou não. O finally
será invocado. Isso pode ser útil quando você faz algo no final de cada bloco. A sintaxe de finally
é a mesma que para try
.
Existe a finally
palavra – chave seguida pelo bloco de código para executar envolto em chaves. Não há parênteses, mesmo opcional.
// Create try...catch...finally statement
try {
// Run some code
}
catch(err) {
// Log any error message
console.log(err)
}
finally {
// Do something whether is an error or not
}
// Example:
try {
// Try to invoke non-existing function
myFunc()
}
catch(err) {
// Log any error message
console.log(err.message)
}
finally {
// Log a message at the end of execution of the try...catch...finally statement
console.log('The end of try...catch...finally statement.')
}
// Outputs:
// 'myFunc is not defined'
// 'The end of try...catch...finally statement.'
Captura um tanto opcional
Até agora, sempre cometíamos erros ao usar todos os blocos try...catch
ou try...catch...finally
instruções. Uma coisa que você deve saber é que o catch
é, da mesma forma que o finally
, também é opcional. Dito isto, isso não significa que é uma boa idéia omitir isso.
Quando você omite o catch
bloco, qualquer erro que ocorra durante a execução do try
bloco “vazará” para fora. Sem o catch
bloco, não há nada que capte algum erro e o processe. Então, você pode omiti-lo? Sim. Você pode usar apenas try
ou try...finally
. Ambos, vai funcionar. No entanto, nenhum erro será detectado.
// Create try statement
try {
myFunc()
}
// Create try...finally statement
try {
myFunc()
}
finally {
console.log('try...finally is finished.')
}
Tente… pegar a instrução dentro das funções
Todo o tratamento de erros anterior mostra cantar try...catch
em um escopo global, fora de quaisquer funções. Isso não significa que a try...catch
declaração esteja restrita ao escopo global. Não é. Você pode usar em um escopo global ou local, criado por uma função, por exemplo. Isso também funcionará.
// Declare new function that takes one parameter
function myFunction(name) {
// Add try...catch statement
try {
// If value passed as name parameter is not a string
if (typeof name !== 'string') {
// Throw a TypeError
throw new TypeError('The name value of parameter must be a string!')
} else {
console.log(`Hello ${name}.`)
}
}
catch(err) {
// Log
console.log(err)
}
}
myFunction(11)
// Outputs:
// TypeError: The name value of parameter must be a string!
// at myFunction (eval at <anonymous> (:7:47), <anonymous>:6:13)
// at eval (eval at <anonymous> (:7:47), <anonymous>:13:1)
// at <anonymous>:7:47
// at <anonymous>:19:23
// ...
myFunction('Jack')
// Outputs:
// 'Hello Jack.'
Criando e lançando erros
Para tratamento de erros, você pode usar erros JavaScript integrados ou pode definir seus próprios. Nas duas abordagens, você usará a throw
instrução Esta declaração especifica o valor que você deseja lançar como um erro. Você já usou esta declaração no exemplo na seção “Experimente, captura e controle”, dentro do declaration myFuncWithError() function
.
Criando erros simples
Vamos dar uma olhada na primeira maneira de criar um erro personalizado. Este será um erro muito simples. Você fará isso usando uma throw
instrução com uma string, número ou qualquer outro tipo de dados . Por exemplo, vamos criar uma função simples que, quando você a chama, gera um erro personalizado. Este erro personalizado será uma sequência.
// Create function
function myFunc() {
// Throw a custom error
throw 'My custom error.'
}
// Create try...catch statement
try {
// Invoke the myFunc() function
myFunc()
}
catch(err) {
// Log the error
console.log('Error: ', err)
console.log('Error name: ', err.name)
console.log('Error message: ', err.message)
console.log('Error stack: ', err.stack)
}
// Outputs:
// 'Error: ' 'My custom error.'
// 'Error name: ' undefined
// 'Error message: ' undefined
// 'Error stack: ' undefined
Como você pode ver, é fácil criar um erro simples. A desvantagem de criar erros desta maneira é que esses erros personalizados não terá name
, message
e stack
propriedades. Existe uma maneira de corrigir isso. Uma maneira simples de fazer isso é usar um objeto em vez de um tipo de dados primitivo.
Então, em vez de jogar uma string ou outra primitiva, você jogará um objeto. Dentro deste objeto, você definirá todas as propriedades que normalmente existiriam em um objeto de erro, the name
, message
e stack
. Agora, quando esse erro personalizado ocorre, você também pode acessar seus name
, message
e stack
.
// Create function
function myFunc() {
// Throw a custom error object
throw {
name: 'MyCustomError',
message: 'An error occurred.',
stack: 'myFunc()'
}
}
try {
// Invoke the myFunc() function
myFunc()
}
catch(err) {
// Log the error
console.log('Error: ', err)
console.log('Error name: ', err.name)
console.log('Error message: ', err.message)
console.log('Error stack: ', err.stack)
}
// Outputs:
// 'Error: ' {
// name: 'MyCustomError',
// message: 'An error occurred.',
// stack: 'myFunc()'
// }
// 'Error name: ' 'MyCustomError'
// 'Error message: ' 'An error occurred.'
// 'Error stack: ' 'myFunc()'
Criando erros com construtores de erro internos do JavaScript
Outra opção para a criação de novos erros é usando JavaScript embutido construtores de erro, como Error
, TypeError
, ReferenceError
, SyntaxError
, RangeError
, EvalError
, InternalError
e URIError
. Você usará a throw
instrução para gerar esses erros personalizados também. Você também precisará usar a palavra-chave new
junto com um dos nomes do construtor.
A new
palavra-chave diz que você está criando uma nova instância de um construtor. Nesse caso, algum construtor de erros. Quando você usa um desses construtores, a name
propriedade dentro do error
objeto será o construtor que você usou. O message
será a seqüência que você passar como um argumento quando você instancia o construtor.
// Create function
function myFunc() {
// Throw a custom error using Error constructor
// The Error will be the "name" property in error object
// The 'An error occurred.' will be the "message" property in error object
throw new Error('An error occurred.')
}
try {
myFunc()
}
catch(err) {
console.log('Error: ', err)
console.log('Error name: ', err.name)
console.log('Error message: ', err.message)
console.log('Error stack: ', err.stack)
}
// Outputs:
// 'Error: ' Error: An error occurred.
// at myFunc (eval at <anonymous> (:7:47), <anonymous>:4:9)
// at eval (eval at <anonymous> (:7:47), <anonymous>:8:3)
// at <anonymous>:7:47
// at <anonymous>:20:9
// ...
// 'Error name: ' 'Error'
// 'Error message: ' 'An error occurred.'
// 'Error stack: ' `Error: An error occurred.
// at myFunc (eval at <anonymous> (:7:47), <anonymous>:4:9)
// at eval (eval at <anonymous> (:7:47), <anonymous>:8:3)
// at <anonymous>:7:47
Criando erros personalizados com o construtor Function e a classe
Juntamente com os construtores de erro internos do JavaScript, você também pode criar erros personalizados com o construtor ou a classe Function . Aqui está como. Você precisa usar o construtor de funções para criar um novo erro personalizado. Este construtor de função terá um parâmetro quando você o usar. Esta será a mensagem de erro.
Dentro deste construtor, você irá adicionar três propriedades, name
, message
e stack
. A name
propriedade conterá o nome do seu erro personalizado. O message
irá se referir ao valor passado como message
parâmetro. O stack
usarástack
propriedade do Error
construtor instanciado recentemente .
Quando você tem isso, é necessário definir a prototype
propriedade desse novo construtor Function como construtor de erros. Por fim, você também deve definir a constructor
propriedade do construtor Function em prototype
property para o construtor Function. Quando você tem isso, usa throw
e new
instruções para criar novos erros com base no seu construtor de erros customizado.
// Create new custom error using Function constructor
const MyCustomError = function(message) {
// Add name property with some custom name
this.name = 'MyCustomError'
// Add message property referencing the value passed as "message" parameter
this.message = message
// Add stack property from Error constructor
this.stack = (new Error()).stack
}
// Set "prototype" property of custom error constructor to Error constructor
MyCustomError.prototype = new Error()
// Set the "constructor" property of custom error constructor to the custom error constructor
MyCustomError.prototype.constructor = MyCustomError
// Usage:
// Create function
function myFunc() {
// Use custom error constructor to create new error
throw new MyCustomError('An error occurred.')
}
// Create try...catch statement
try {
// Invoke function with custom error
myFunc()
}
catch(err) {
// Log error data
console.log('Error: ', err)
console.log('Error name: ', err.name)
console.log('Error message: ', err.message)
console.log('Error stack: ', err.stack)
}
// Outputs:
// 'Error: ' Error
// at new MyCustomError (eval at <anonymous> (:7:47), <anonymous>:6:16)
// at myFunc (eval at <anonymous> (:7:47), <anonymous>:13:9)
// at eval (eval at <anonymous> (:7:47), <anonymous>:17:3)
// at <anonymous>:7:47
// at <anonymous>:26:9
// ...
// 'Error name: ' 'MyCustomError'
// 'Error message: ' 'An error occurred.'
// 'Error stack: ' `Error
// at new MyCustomError (eval at <anonymous> (:7:47), <anonymous>:6:16)
// at myFunc (eval at <anonymous> (:7:47), <anonymous>:13:9)
// at eval (eval at <anonymous> (:7:47), <anonymous>:17:3)
// at <anonymous>:7:47
// at <anonymous>:28:9
// ...
Com a classe JavaScript, criar um construtor de erros personalizado é ainda mais fácil. Primeiro, você deve criar uma nova classe para o construtor de erros personalizado. Esta classe será extend
aError
classe. Dentro da classe, você adicionará constructor
com um parâmetro. Esta será a mensagem de erro.
Dentro do constructor
, você tem que chamar super
com message
passado como argumento. Isso chamará o construtor da classe pai Error
. Depois disso, ainda dentro do constructor
, você substituirá a name
propriedade adicionando sua própria name
propriedade com o nome do seu construtor personalizado.
// Create new error constructor with JavaScript class
class MyCustomError extends Error {
constructor(message) {
// Call constructor of parent class Error
super(message)
// Set your custom error name
this.name = 'MyCustomError'
}
}
// Create try...catch statement
try {
// Throw new custom error
throw new MyCustomError('An error occurred')
}
catch(err) {
console.log('Error name: ', err.name)
console.log('Error message: ', err.message)
console.log('Error stack: ', err.stack)
}
// Outputs:
// 'Error name: ' 'MyCustomError'
// 'Error message: ' 'An error occurred'
// 'Error stack: ' `MyCustomError: An error occurred
// at eval (eval at <anonymous> (:7:47), <anonymous>:12:9)
// at <anonymous>:7:47
// at <anonymous>:23:9
// ...
Erro ao manipular globalmente
O try...catch
etry...catch...finally
declarações são poderosas. Esses dois podem facilitar o tratamento de erros. Um problema pode ser se você não conseguir isolar o código que deseja executar com o try
bloco. Por exemplo, quando algum código é executado em um escopo global a partir de um local onde você não pode acessá-lo.
Nesse caso, você pode usar o onerror()
método Este é um manipulador de eventos de erro. Você pode usá-lo para capturar e processar erros que ocorrem em um escopo global. Além do window
objeto, você também pode usá-lo com elementos no DOM. Como alternativa, você pode anexar um novo ouvinte de error
evento para evento, em um window
ou em algum elemento.
// Option no.1: onerror() method
window.onerror = function(message, url, lineNumber, columnNumber, error) {
console.log(`
error message: ${message},
error URL: ${url},
line with error: ${lineNumber},
column with error: ${columnNumber}
`)
}
// Option no.2: listening to 'error' event
window.addEventListener('error', function(event) {
console.log(`
error message: ${event.message},
error URL: ${event.filename},
line with error: ${event.lineno},
column with error: ${event.colno},
error object: ${JSON.stringify(event.error)}
`)
})
Conclusão: Tratamento de erros em JavaScript
Parabéns! Você acabou de concluir este tutorial sobre tratamento de erros em JavaScript. Espero que tenha gostado. Se você me acompanhou, deve ter uma boa idéia sobre como lidar com erros no JavaScript. Você deve saber o que são erros de sintaxe e tempo de execução e qual é a diferença entre eles.
Você também deve saber como a try...catch
instrução, e Finally
, funciona, e como usá-la, executa seu código e captura os erros que ocorrerem. Você também sabe como lançar erros internos do JavaScript. Não apenas isso. Você também sabe como criar seus próprios erros com primitivas, construtores de funções e classes JavaScript.
E, se ocorrer algum erro em um escopo global, você saberá como usar o onerror()
método ou o ouvinte de evento de erro para detectá-lo. Agora depende de você pegar o que aprendeu neste tutorial sobre tratamento de erros e usá-lo para escrever um código melhor e mais seguro.
Que material incrível! Estou começando agora na programação e estava com bastante duvidas sobre o try catch e throw.. esse artigo ficou bem completinho! ajudou muito obg
Material incrível, porém, tive que diminuir o zoom da página para 80% para conseguir ler, em 100% muitas palavras estão fora de visão do lado direito, espero ter ajudado