5
respostas

Local do catch

Vi que você colocou o catch no nível da Promise de getConnection().

Dúvida: esse catch vai pegar também a exceção que for lançada na Promise de adiciona() do NegociacaoDao?

5 respostas

Boa noite, Reinaldo! Como vai?

Eu fiz o seguinte teste aqui pra ilustrar a resposta da sua pergunta:

function getConnection() {
    return new Promise((resolve, reject) => {
        resolve('Conexão enviada');
    });
}

function adiciona() {
    return new Promise((resolve, reject) => {
        reject('Erro ao inserir informação');
    });
}

getConnection()
    .then(res => {
        console.log(res);
        adiciona()
            .then(res => console.log(res));
    })
    .catch(err => console.error(err));

E o resultado no console do navegador foi Uncaught (in promise) Erro ao inserir informação.

Portanto, dessa forma que é igual ao que o mestre Flávio fez no curso, se ocorrer um reject() na Promise retornada pelo método adiciona() o catch() não conseguiria pegar.

Para resolver isso há duas formas! Ou retornamos a Promise do método adiciona()

getConnection()
    .then(res => {
        console.log(res);
        return adiciona()
                .then(res => console.log(res));
    })
    .catch(err => console.error(err));

Ou então retorna a mesma Promise e a trata antes do catch().

getConnection()
    .then(res => {
        console.log(res);
        return adiciona();
    })
    .then(res => console.log(res))
    .catch(err => console.error(err));

Ambas as formas farão com que o fluxo do código chegue ao catch().

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!

Não sei se entendi bem.. Mas fiz o seguinte teste:

1) Em NegociacaoDao eu retorno a Promise sem tratar o catch:

add(negociacao) {
        return new Promise((resolve, reject) => {
            let request = this._connection
                .transaction([this._store], 'readwrite')
                .objectStore(this._store)
                .add(negociacao);

            request.onsuccess = event => resolve();

            request.onerror = event => {
                console.log(event.target.error);
                reject(new Error('Erro ao adicionar a Negociação.'));
            }
        });
    }

Em NegociacaoService, que chama o Dao, também retorna a Promise sem tratar o catch:

incluir(negociacao) {
        return ConnectionFactory.get()
        .then(connection => new NegociacaoDao(connection))
        .then(dao => dao.add(negociacao))        
    }

Somente em NegociacaoController eu dou o catch, que de fato é o único que sabe o que fazer quando uma exceção é lançada nesse processo: exibir uma mensagem para o usuário. Ficou assim:

this._negociacaoService
        .incluir(negociacao)
        .then(() => {
            this._listaNegociacoes.add(negociacao);
            this._mensagem.texto = 'Negociação incluída com sucesso.'
            this._cleanForm();
        })
        .catch(error => this._mensagem.texto = error.message);

Daí fiz testes lançando manualmente um Erro tanto no Dao quanto no Service e o Controller capturou ambos.

Opa, Reinaldo! Eu baixei o código do projeto disponibilizado pelo instrutor e fiz os mesmos testes que eu descrevi no meu primeiro comentário tendo obtido os mesmos resultados. Provavelmente vc fez alguma coisa diferente em relação aos testes que fiz e exemplifiquei aqui. Se quiser que eu dê uma olhada é só compartilhar os códigos de teste que vc fez para que eu possa tentar te ajudar a entender o motivo da diferença entre os resultados.

Apenas pra exemplificar novamente, deixarei meu código a seguir.

// ConnectionFactory.js

var ConnectionFactory = (function () {

    return class ConnectionFactory {

        static getConnection() {

            return new Promise((resolve, reject) => {

                resolve('ConnectionFactory - getConnection resolvido');

            });
        }
    }
})();
// NegociacaoDao.js

class NegociacaoDao {

    adiciona(negociacao) {

        return new Promise((resolve, reject) => {
            reject('NegociacaoDao - adiciona rejeitado');
        });
    }
}
// NegociacaoController.js

class NegociacaoController {

    adiciona(event) {

        event.preventDefault();

        ConnectionFactory
            .getConnection()
            .then(connection => {

                console.log(connection);
                new NegociacaoDao(connection)
                    .adiciona();                
            })
            .catch(err => console.error(err));
    }
}

Vc vai ver que com esse código o erro irá estourar dentro do NegociacaoDao na linha do reject() e não no catch().

Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!

Segue código fonte: https://1drv.ms/u/s!Aql0Sg5dfanRhRM27MA7VjgoWQwR?e=nuHSaJ

Reinando, acabei de olhar o seu código! No seu caso os testes deram diferente do meu pois vc está usando a classe NegociacaoService e o método incluir() dessa mesma classe. Sendo que esse método já está implementando a segunda solução para o problema que eu citei no meu primeiro comentário. Por isso que ao lançar o erro o catch() final consegue capturá-lo! Se o seu código estive exatamente como o visto nessa aula vc veria o comportamento que te falei.

Qualquer coisa é só falar!

Grande abraço e bons estudos, meu aluno!