‫Instrutor: Nesta aula, vamos implementar uma maneira melhor
‫de detectar erros em todas as nossas funções assíncronas.
‫Então, agora, em todas as nossas
‫funções assíncronas, temos esses blocos try catch, certo?
‫Portanto, lembre-se de como adicionamos a todas essas funções de manipulação este bloco de
‫tentativa e, em seguida, este bloco de captura, certo?
‫E todos eles têm isso porque
‫todos eles são funções assíncronas e
‫é assim que geralmente pegamos os erros dentro
‫de uma função assíncrona.
‫Então, usando um bloco try catch.
‫Agora, isso realmente faz nosso código parecer confuso e sem foco,
‫então o objetivo deste método createTour aqui, por exemplo, é
‫apenas executar este código.
‫Na verdade, não queremos mexer
‫com o tratamento
‫de erros aqui, então agora temos esses dois blocos
‫extras, try and catch, e com
‫isso vem essa indentação extra aqui
‫e então, novamente, isso realmente faz nosso código não parecer limpo.
‫Realmente não está focado.
‫Além disso, temos muitos códigos duplicados aqui
‫porque em cada um desses
‫manipuladores, temos um bloco catch bastante semelhante.
‫Então, em tudo isso, tudo o
‫que estamos fazendo é realmente enviar essa resposta.
‫E essa resposta nem seria enviada aqui,
‫mas em nosso middleware de tratamento de erros global, lembre-se,
‫mas esse é outro tópico.
‫Por enquanto, o que
‫estou tentando focar aqui é que
‫esses blocos try catch dentro de cada uma de nossas funções
‫assíncronas não são ideais, então vamos tentar consertar isso.
‫E a solução é basicamente tirar o bloco try
‫catch daqui e colocá-lo em um nível superior
‫em outra função.
‫Então, basicamente o que
‫vamos fazer é
‫criar uma função e, em seguida, envolver essa função assíncrona nessa função.
‫Tudo bem?
‫E então deixe-me chamá-lo de catchAsync.
‫Portanto, catchAsync, e estou chamando-o assim, porque
‫o objetivo desta função
‫é simplesmente capturar nossos erros assíncronos.
‫Tão simples, certo?
‫Então, para esta
‫função catchAsync, vamos passar uma função, ok?
‫E lembre-se, a função que passaremos
‫é basicamente esta.
‫Agora que estamos trabalhando com este exemplo,
‫a função que passaremos para o catchAsync é esta
‫função, porque é aqui que queremos
‫capturar os erros assíncronos.
‫Então, vamos realmente fazer isso.
‫Então fn e, em seguida, envolva toda a função aí.
‫Em seguida, o que temos que fazer
‫é realmente chamar essa função aqui.
‫Então chame-a, e essa função
‫deve receber solicitação, resposta e, de fato, também próxima.
‫Portanto, este aqui também deve ter next e todas as outras
‫também, porque lembre-se
‫de que precisamos da próxima função para
‫passar o erro para ela de
‫forma que esse erro possa ser
‫tratado no middleware de tratamento de erros global.
‫Portanto, todas essas funções precisarão de
‫solicitação, resposta e a próxima.
‫Mas vamos deixar isso para depois.
‫Por enquanto, vamos realmente nos concentrar em nosso catchAsync aqui.
‫Portanto, esta função aqui que passamos para async, que
‫agora é chamada de fn aqui,
‫é uma função assíncrona.
‫E lembre-se de que
‫as funções assíncronas retornam promessas, certo?
‫E quando há um erro dentro de
‫uma função assíncrona, isso basicamente significa que a promessa foi rejeitada.
‫E aqui em cima, onde realmente chamamos essa função,
‫podemos detectar esse erro.
‫Portanto, capturamos aqui, em vez
‫de capturá-lo no bloco try catch.
‫Então, pegue e dê o erro e, em seguida, passe o erro.
‫E podemos
‫simplificar isso, mas, por enquanto, vamos remover o bloco try
‫catch aqui, e simplesmente nos concentrar nesta parte.
‫Isso é tudo
‫o que queremos e não precisamos mais do bloco try
‫catch, de novo, porque esse catch agora é basicamente transferido para
‫aqui, para esta linha.
‫Não é mais um bloco
‫catch, porque aqui é apenas mais
‫fácil usar a promessa de que a função fn retorna.
‫Então, novamente, essa função fn é essa função, então
‫aquela que passamos para catchAsync, e
‫isso vai retornar uma promessa.
‫E, na verdade, percebi aqui que
‫isso, é claro, deveria se chamar catchAsync, certo?
‫E então aquela
‫função que passamos para catchAsync, esta é, obviamente, fn.
‫Tudo bem?
‫Então, o argumento que passamos lá.
‫Na verdade, existem dois grandes problemas com
‫a maneira como isso é implementado
‫agora e, dessa forma, não funcionaria de fato.
‫Portanto, primeiro, esta chamada de função
‫aqui não tem como saber a solicitação, a resposta e a próxima.
‫Não os passamos para catchAsync aqui e,
‫portanto, realmente não há
‫como a função saber os valores desses parâmetros.
‫E a segunda é
‫que bem aqui estamos chamando a função assíncrona.
‫E para ver isso um pouco melhor, vamos
‫nos livrar completamente desse código.
‫Então, aqui temos catchAsync e estamos chamando-o usando
‫os parênteses, é claro.
‫E então, dentro de catchAsync, também estamos
‫chamando imediatamente a função fn, e não é
‫assim que ela deveria funcionar.
‫Portanto, createTour aqui deve ser realmente uma função, mas
‫não o resultado da chamada de uma função.
‫Mas é isso que está acontecendo agora.
‫Então, agora, catchAsync está
‫sendo chamado, que então chama essa função aqui, certo?
‫E então, novamente, esta função não deve ser chamada, mas
‫em vez disso, ela deve ficar aqui e esperar
‫até que o expresso a chame.
‫E o Express irá,
‫é claro, chamá-lo assim que alguém
‫atingir a rota que precisa dessa função de controle.
‫E então a solução para isso é basicamente fazer com
‫que a função catchAsync retorne outra função que
‫será atribuída a createTour e para que essa
‫função possa ser
‫chamada posteriormente quando necessário.
‫Então vamos fazer isso aqui.
‫Vamos retornar uma função anônima e lembrar
‫que essa é a função
‫que express irá chamar.
‫E aqui é onde especificamos
‫a solicitação, a resposta e a próxima.
‫Na verdade, faltando a seta aqui.
‫E tudo bem.
‫E é isso mesmo.
‫Essa é a nossa função catchAsync.
‫Basta lembrar que eu disse
‫que poderíamos simplificá-lo e isso porque,
‫em JavaScript, podemos simplificá-lo assim, então
‫tudo o que precisamos passar aqui é
‫a função, e ela será chamada
‫automaticamente com o parâmetro que este callback recebe.
‫Portanto, é o mesmo que escrever a seguir.
‫Então, vamos recapitular aqui.
‫Portanto, para eliminar nossos blocos try catch,
‫simplesmente envolvemos nossa função assíncrona
‫dentro da função catchAsync que acabamos de criar.
‫Essa função retornará uma nova função
‫anônima, que
‫é esta aqui, que será atribuída a createTour.
‫E então, basicamente, é esta função
‫aqui que será chamada assim que um
‫novo tour for criado usando o manipulador createTour.
‫E é por isso que ela tem exatamente
‫a mesma assinatura aqui que esta função assíncrona, com solicitação, resposta e próximo.
‫Agora, o que esta função aqui
‫fará é chamar a
‫função que passamos inicialmente, esta
‫aqui, e
‫então executará todo o código que está lá.
‫Agora, por se tratar de uma
‫função assíncrona aqui, ela
‫retornará uma promessa e, portanto, caso haja um erro
‫nesta promessa ou em outras palavras, caso seja
‫rejeitada, podemos pegar o erro que aconteceu
‫usando o método catch que é disponível em todas as promessas.
‫E no final, é este método catch que
‫vai passar o erro para a próxima função que
‫fará com que nosso erro
‫termine em nosso middleware de tratamento de erros global.
‫Então é aqui, nessa linha de código,
‫que é realmente onde toda a mágica acontece,
‫e é isso, de fato,
‫o que nos permite livrar-nos do bloco catch que tínhamos anteriormente.
‫E
‫uma nota: isso é bastante complicado de entender
‫e caso não esteja 100% claro, não
‫se preocupe, não é tão importante.
‫Na verdade, trata-se apenas de descobrir como
‫o código assíncrono funciona exatamente nos bastidores em JavaScript.
‫Portanto, não se trata tanto de Express ou Node. js, trata-se
‫mais de como o código assíncrono funciona.
‫De qualquer forma, se agora criarmos um
‫novo tour e
‫algum erro acontecer, por exemplo, de
‫uma entrada inválida, então esse erro deve ser
‫capturado aqui nesta função
‫catch, e então será propagado para nosso middleware de
‫tratamento de erros e para que um enviará de volta
‫a resposta de erro que esperamos receber.
‫E agora vamos realmente tentar isso.
‫Portanto, crie um novo tour.
‫Aqui temos o corpo
‫e agora vamos nos livrar de um desses campos obrigatórios.
‫Tudo bem.
‫Isso deve causar um erro, e vamos ver.
‫E, de fato, nossa validação de tour falhou, que
‫é exatamente a mensagem
‫de erro que deveríamos receber.
‫Agora aqui, você vê este 500 Erro Interno do Servidor, que é simplesmente
‫devido ao fato de que agora o
‫erro que foi propagado para o
‫middleware de tratamento de
‫erros não tinha nenhum código de status especificado
‫e, portanto, lembre-se de que nosso padrão é 500
‫e esse é o que foi então enviado de volta.
‫E, claro, precisamos consertar isso
‫e faremos isso em uma aula posterior neste curso.
‫Por enquanto, o que importa aqui
‫é que, primeiro, nossa função catchAsync funciona exatamente como pretendido
‫e, segundo, que o erro foi realmente propagado, portanto,
‫foi detectado por nosso middleware de tratamento de erros
‫global, que então enviou essa resposta de volta ao cliente.
‫Agora, vamos realmente exportar essa função
‫catch para seu próprio arquivo.
‫Então, estou pegando aqui e
‫vou criar apenas outro arquivo em
‫nossa pasta de utilitários.
‫Então, catchAsync. js.
‫E até aqui, módulo. as exportações devem ser apenas isso.
‫E isso deve funcionar bem.
‫De volta ao nosso tour controller,
‫é claro que agora precisamos importar esta função.
‫E como de costume, precisamos subir uma pasta
‫e, em seguida, em nossa pasta de
‫utilitários e, em seguida, catchAsync.
‫Tudo bem, e agora
‫tudo o que precisamos fazer é nos livrar
‫de todos esses blocos catch e envolver todos os manipuladores no catchAsync.
‫Então vamos fazer isso.
‫Primeiro faça o embrulho e depois livre-se desses blocos.
‫Salve para reformatar e aqui vamos nós.
‫E agora é simplesmente um processo de
‫repetir isso até todos os passeios, ou, desculpe, até
‫que todos os manipuladores tenham terminado.
‫Ok, salvamento rápido.
‫Este já está feito.
‫O próximo passo é a atualização.
‫E apenas mais um faltando.
‫Ou, na verdade, isso não é verdade.
‫Lá embaixo, temos ainda mais funções assíncronas.
‫Portanto, vamos nos livrar do problema e tentar aqui.
‫E acredito que este seja o último.
‫E sim, realmente é.
‫Tudo bem, agora outra coisa que
‫precisamos fazer é adicionar o próximo a todos eles aqui também.
‫Mas, claro, não em maiúsculas.
‫OK.
‫E deixe-me selecionar todos eles aqui para que
‫eu tenha que escrever apenas uma vez.
‫E isso adicionou a todos eles.
‫E agora acho que terminamos com essa parte.
‫Vamos testá-lo rapidamente de novo, não com
‫este, mas aqui, não com
‫este também, então terminamos.
‫E vou tentar fazer
‫um tour, mas com uma identificação inválida, então vamos ver o que acontece aqui.
‫E, de fato, recebemos nossa mensagem de
‫erro e novamente com o código de
‫status 500, que não
‫está correto, lembre-se,
‫mas cuidaremos disso mais tarde.
‫Então, agora, deixe-me mostrar que é daqui
‫que vem o 500, porque agora não há código de status
‫dentro do erro que recebemos
‫porque esses erros, na
‫verdade, vêm do Mongoose e, portanto, não temos
‫como adicionar
‫um status código para esses erros.
‫Ou, na verdade, é claro, poderíamos fazer isso,
‫mas ficaria ainda mais confuso e,
‫portanto, encontraremos outra maneira mais tarde
‫nesta seção.
‫Por enquanto, estou muito feliz com o resultado que temos
‫aqui e isso é tudo para essa palestra.