Tratando Erros em Promises com JavaScript
Um dos benefícios das promises é a maneira mais simples de lidar com erros. Para capturar e tratar um erro, podemos utilizar a função catch()
do objeto Promise
, que aceita uma função de tratamento de erros como parâmetro:
const myPromise = new Promise(function (resolve, reject) {
console.log("Executando operação assíncrona");
reject("Dados incorretos");
});
myPromise.catch(function (error) {
console.log(error);
});
A função catch()
recebe um manipulador de erros como parâmetro. O parâmetro desta função é o valor que é passado ao reject()
.
Saída do Console:
Executando operação assíncrona Dados incorretos
Lançando Erros
Anteriormente, a função reject()
foi chamada para sinalizar um erro. No entanto, é importante notar que um erro pode ocorrer sem a chamada de reject()
. Se um erro é lançado durante uma operação dentro de uma promise por algum motivo, toda a operação também termina em erro. Por exemplo, no código a seguir, é chamada uma função inexistente getSomeWork()
:
const myPromise = new Promise(function (resolve) {
console.log("Executando operação assíncrona");
getSomeWork(); // chamada de uma função não existente
resolve("Hello world!");
});
myPromise.catch(function (error) {
console.log(error);
});
Como a função getSomeWork()
não é declarada, a execução da tarefa assíncrona termina em erro e não chega a chamar resolve("Hello world!")
. Portanto, a função de tratamento de erros do catch()
é ativada, recebendo através do parâmetro error
a informação sobre o erro ocorrido, e a mensagem de erro é exibida no console do navegador:
Executando operação assíncrona Uncaught ReferenceError: getSomeWork is not defined at Promise (index.html:10) at new Promise (<anonymous>) at index.html:9
throw
O erro também pode ser resultado do uso do operador throw, que lança um erro:
const myPromise = new Promise(function (resolve, reject) {
console.log("Executando operação assíncrona");
const parsed = parseInt("Hello");
if (isNaN(parsed)) {
throw "Not a number"; // Lança um erro
}
resolve(parsed);
});
myPromise.catch(function (error) {
console.log(error);
});
Aqui, uma string aleatória é convertida em número. Se o resultado da conversão não for um número, um erro é lançado usando o operador throw
. Isso leva ao término da função com um erro, e o resultado é tratado pela função catch
:
Executando operação assíncrona Not a number
Neste caso, a função manipuladora recebe a mensagem de erro especificada após o operador throw
.
Esta situação pode parecer artificial, pois não há razão para lançar um erro usando throw
no código acima, já que também podemos passar a mensagem de erro para a função reject
:
if (isNaN(parsed)) {
reject("Not a number");
}
No entanto, o operador throw
pode ser usado em uma função externa que chamamos no código:
function getNumber(str) {
const parsed = parseInt(str);
if (isNaN(parsed)) throw "Not a number"; // Lança um erro
else return parsed;
}
const myPromise = new Promise(function (resolve) {
console.log("Executando operação assíncrona");
const result = getNumber("hello");
resolve(result);
});
myPromise.catch(function (error) {
console.log(error);
});
Aqui, a conversão de uma string em número é realizada em uma função externa, getNumber
. No entanto, ao chamar essa função em uma promise, um erro também pode surgir do operador throw
, e consequentemente a função catch()
será chamada para tratar o erro.
try..catch
Assim como em casos gerais, operações que podem lançar erros podem ser colocadas dentro de uma estrutura try
..catch
, e quando uma exceção ocorre no bloco catch
, a função reject()
é chamada:
const myPromise = new Promise(function (resolve, reject) {
try {
console.log("Executando operação assíncrona");
getSomeWork(); // chamada de uma função não existente
resolve("Hello world!");
} catch (err) {
reject(`Ocorreu um erro: ${err.message}`);
}
});
myPromise.catch(function (error) {
console.log(error);
});
Saída do Console:
Executando operação assíncrona Ocorreu um erro: getSomeWork is not defined
Tratando Erros Usando then
Além da função catch
para capturar e tratar erros, podemos também utilizar a função then()
. O segundo parâmetro de then()
é um manipulador de erros, que recebe o valor passado pela função reject()
:
promise.then(
function (value) {
// obtenção do valor
},
function (error) {
// tratamento do erro
}
);
O segundo parâmetro da função then()
é um manipulador de erros. Usando o parâmetro error no manipulador, podemos obter o valor passado ao reject()
, ou informações sobre o erro ocorrido.
Exemplo:
function generateNumber(str) {
return new Promise(function (resolve, reject) {
const parsed = parseInt(str);
if (isNaN(parsed)) reject("o valor não é um número");
else resolve(parsed);
}).then(
function (value) {
console.log("Resultado da operação:", value);
},
function (error) {
console.log("Ocorreu um erro:", error);
}
);
}
generateNumber("23");
generateNumber("hello");
Neste caso, para permitir passar diferentes dados ao promise, ele é definido como o resultado retornado pela função generateNumber()
. Assim, a saída no console será a seguinte:
Resultado da operação: 23 Ocorreu um erro: o valor não é um número