‫Palestrante: Olá.
‫Vamos agora renderizar algumas páginas de erro interessantes para nossos usuários.
‫E então, para começar, vamos criar um erro primeiro.
‫Então, vamos abrir este tour aqui.
‫Não, eu não quero traduzir.
‫E agora vamos simplesmente adicionar algo a este log aqui, e
‫então, é claro, isso não será encontrado.
‫Certo, então é assim que um erro se parece
‫neste ponto.
‫Então, simplesmente, tudo isso
‫JSON aqui, assim como seria no Postman.
‫Portanto, já vimos esse tipo de erro aqui antes.
‫E então, vamos corrigir isso agora.
‫Mas primeiro precisamos corrigir esse erro específico.
‫Portanto, agora chegamos,
‫não é possível ler o nome da propriedade null em getTour.
‫OK.
‫E isso está aqui em nosso controlador de visualizações, getTour.
‫E então aqui, não temos nenhum
‫tratamento de erros caso não haja um tour, certo?
‫Portanto, temos isso em todos os nossos outros gerenciadores
‫de rota, mas, neste, ainda não temos.
‫Então, vamos adicionar isso.
‫Portanto, se não houver um tour, volte e vá para
‫o próximo middleware com um novo erro de aplicativo.
‫E provavelmente ainda não está aqui.
‫E não, de fato, não é.
‫Então const.
‫AppError é igual a.
‫Tudo bem.
‫Erro aqui, é claro.
‫E então vamos dizer
‫que não há turnê com esse nome.
‫E então é um 404 para não encontrado.
‫OK?
‫Então, vamos tentar de novo.
‫E agora devemos obter um erro muito melhor.
‫E, de fato, temos um.
‫Então, 404.
‫E lembre-se de que este agora é um erro operacional.
‫Portanto, um erro que sabemos que basicamente criamos a nós mesmos.
‫E, assim como antes, isso será importante para nossa
‫estratégia de tratamento de erros.
‫Então, vamos realmente falar sobre isso.
‫E aqui terminamos.
‫E agora em nosso controlador de
‫erro, temos, lembre-se, duas funções que enviam os erros
‫de volta ao cliente.
‫Portanto, temos este aqui para desenvolvimento
‫e este para produção.
‫Em seguida, na produção,
‫distinguimos entre erros operacionais e outros erros desconhecidos.
‫Direito?
‫E isso é realmente o que acabamos de falar antes.
‫Portanto, para os erros que
‫conhecemos, enviamos de volta a mensagem de erro real porque
‫podemos ter certeza de que não será algum
‫erro de aparência
‫estranha vindo de algum lugar do expresso ou
‫nota ou algo parecido.
‫Enquanto, por outro lado, quando é um erro desconhecido, bem,
‫então não queremos vazar os detalhes do erro.
‫E agora, neste caso, com
‫o site renderizado, usaremos a mesma estratégia.
‫Agora, o que vou
‫fazer é simplesmente adicionar a renderização de uma página de
‫erro a cada uma dessas funções.
‫E basicamente, o que vou fazer
‫é testar se a URL começa com API de barra.
‫E então nesse caso, enviamos esse tipo de erro, certo.
‫Mas se a URL não começar com API, bem, nesse caso,
‫significa que queremos renderizar uma página de
‫erro como um site renderizado, certo?
‫Assim como estivemos fazendo nesta seção.
‫De qualquer forma, vamos implementar isso agora.
‫E assim, podemos usar a URL original do ponto de solicitação.
‫E provavelmente já usamos isso antes.
‫Tudo bem?
‫Portanto, o URL original é basicamente o URL inteiro, mas não
‫com o host.
‫Então parece exatamente como a rota.
‫E então, novamente, quando estamos acessando nosso URL,
‫bem, então essa rota começa com a API de barra.
‫E agora podemos testar isso.
‫Portanto, podemos usar uma função JavaScript chamada startsWith.
‫Portanto, uma função que está disponível para strings.
‫E então teste se ele começa com a API slash.
‫Direito?
‫E se isso acontecer, é isso que queremos fazer.
‫Portanto, basta enviar o erro como JSON.
‫Mas se não, bem, então realmente queremos processar um erro.
‫Portanto, ainda está res. status.
‫E para statusCode também.
‫Mas aqui é realmente renderizado.
‫Em seguida, obtemos o nome do
‫modelo e vamos criá-lo em um segundo, mas
‫ele se chamará erro.
‫E então os dados que queremos enviar são,
‫por enquanto, apenas o título.
‫E vou adicionar mais algumas
‫coisas, quando o modelo estiver realmente pronto.
‫Portanto, algo deu errado será o título desta
‫página de erro.
‫Tudo bem?
‫Oh, na verdade não temos
‫acesso à variável de solicitação aqui.
‫E sua função.
‫E então vamos adicionar isso.
‫Solicite aqui.
‫E também vamos precisar disso aqui.
‫Este.
‫E então vamos adicionar isso aqui também.
‫Bem aqui.
‫OK.
‫Então, agora precisamos criar essa página, ou esse
‫modelo, chamado de erro.
‫E mais uma vez, já tenho um template simples para isso.
‫Portanto, está em dev-data, templates e errorTemplate.
‫OK?
‫Então, vamos copiar isso.
‫Em seguida, crie uma visualização para isso.
‫erro. pug.
‫OK.
‫E aqui temos um h2 simples que diz, uh
‫oh, algo deu errado.
‫Então (risos) alguns emojis divertidos lá.
‫Eles não são realmente divertidos.
‫E aqui também queremos ser capazes de passar uma mensagem.
‫Tudo bem?
‫Então, vamos adicionar isso igual a msg, apenas uma abreviação para mensagem.
‫Tudo bem?
‫E é isso mesmo.
‫Então, vamos fechar isso e passar essa mensagem.
‫Então msg está definido.
‫E vamos realmente configurá-lo para mensagem de ponto de erro.
‫OK?
‫E estamos fazendo aqui porque estamos em desenvolvimento.
‫Portanto, mantenha isso em mente.
‫Vamos também adicionar alguns comentários aqui.
‫API.
‫Vamos colocar isso aqui.
‫O site renderizado.
‫Então estamos fazendo assim, com mensagem de erro, novamente
‫porque no desenvolvimento,
‫realmente não importa se vazarmos todos os detalhes do
‫erro para nossa página, certo?
‫Porque ninguém vai realmente ver, já que, sim,
‫estamos em desenvolvimento.
‫Então, isso deve estar funcionando agora.
‫Portanto, tudo o que precisamos fazer agora é recarregar esta página.
‫Mas agora algo está errado aqui.
‫Portanto, ele diz que não enviou nenhum dado.
‫Então, vamos voltar aqui.
‫Bem, como primeiro problema que estou
‫vendo aqui, devo ter o código de status e não apenas o status.
‫Isso é tudo para verificar se há algum erro aqui.
‫Oh sim.
‫Na verdade, existem erros.
‫Então, na verdade, era o código de status inválido.
‫Portanto, aqui deve estar o código.
‫Vamos dar outra defesa.
‫Recarregue-o.
‫E agora temos alguma página de erro aqui.
‫Bem, não está realmente formatado.
‫Mas ainda assim, ele tem o título e,
‫mais importante, tem essa mensagem que acabamos de transmitir.
‫Portanto, não há turnê com esse nome.
‫E isso vem exatamente do nosso controlador de visualizações.
‫Então, direto daqui.
‫Portanto, lembre-se da lógica em que criamos um erro aqui, que
‫é então passado para o nosso erro
‫global e middleware Lint.
‫Direito?
‫E é isso que vai pegar
‫esses erros e enviá-los para o cliente.
‫Agora, em nosso caso, recebemos esse
‫erro porque aqui em nosso modelo, ainda esquecemos
‫de fazer algo.
‫O que é simplesmente estender, é claro, nosso modelo principal.
‫Direito?
‫Portanto, precisamos dizer extend to base template.
‫E então, como sempre, crie esse bloco aqui.
‫Portanto, bloqueie o conteúdo.
‫E então tudo isso precisa estar lá.
‫E basicamente aqui estamos fazendo
‫exatamente a mesma coisa que fizemos em todos os outros modelos.
‫Então, basicamente injetando esse conteúdo
‫aqui no blog de conteúdo no modelo base.
‫Portanto, se recarregarmos agora, ele finalmente terá a aparência desejada.
‫Tudo bem?
‫E agora, se realmente tivemos algum erro em nosso código, e
‫então vamos dizer novamente que não
‫temos esse tratamento de erro aqui, então é
‫claro que todo o erro vazou para o cliente.
‫Portanto, não é possível ler o nome da propriedade de null.
‫E, claro, não queremos que os visitantes do nosso
‫site recebam esse tipo de erro, certo?
‫Ninguém entenderia realmente o que isso significa.
‫E então, em nosso manipulador de erros de produção,
‫vamos cuidar disso agora.
‫Então, aqui em nosso controlador de erro,
‫agora vamos aplicar a mesma lógica que temos aqui.
‫Portanto, testando se estamos lidando com a API ou não.
‫E, claro, pode haver maneiras mais elegantes de
‫fazer isso.
‫Por exemplo, você poderia ter um middleware
‫de tratamento de erros completamente separado apenas para a
‫API e um para o site renderizado, certo?
‫Mas, novamente, eu só quero mantê-lo um tanto simples aqui.
‫OK?
‫Nesse caso, esse é realmente meu objetivo principal.
‫Tudo bem.
‫Vamos selecionar tudo isso.
‫Oh, o que aconteceu ai?
‫Ah, aqui vamos nós.
‫OK.
‫Então, isso é para a API.
‫E agora teremos algo muito semelhante.
‫Portanto, este é, novamente, para o site renderizado.
‫Vamos chamá-lo de B aqui e A neste caso.
‫Então, só para separar um pouco melhor.
‫Então nós temos e B aqui embaixo.
‫De qualquer forma, isso será um pouco parecido com este.
‫E se tivermos um erro operacional, basicamente a página
‫de erro
‫deve ser semelhante à anterior.
‫Mas no caso de ser um erro de programação
‫ou desconhecido, então não queremos a mensagem completa, mas
‫apenas uma mensagem muito genérica.
‫Então, algo como, por favor, tente novamente mais tarde.
‫Tudo bem?
‫Agora vamos ver que tipo de erro obtemos aqui.
‫E, aparentemente, temos algo chamado de
‫declaração if solitária aqui.
‫Direito.
‫Então, sim, o Lint realmente
‫não quer que tenhamos apenas um if dentro de um bloco else.
‫E eu concordo que não
‫é uma prática de codificação bonita.
‫E então, de fato, vamos consertar
‫isso nos livrando disso aqui.
‫Dê uma chance.
‫E então esse erro desaparece.
‫Mas agora precisamos ter certeza de que isso aqui
‫realmente encerra o ciclo de resposta da solicitação.
‫E então precisamos voltar aqui e aqui também.
‫Tudo bem.
‫Agora, outro erro ESLint, desnecessário depois de um retorno.
‫E, de fato, isso também é verdade.
‫E, na verdade, tenho seguido essa
‫regra ao longo do curso porque gosto dela como
‫prática de codificação.
‫E então, sim, vamos nos livrar disso aqui então.
‫Eu realmente acredito, e tenho acreditado por muito tempo,
‫que parece muito melhor sem essas declarações if else, mas em vez
‫disso, apenas com um if, como este aqui e, em
‫seguida, incluir o else fora disso.
‫Ok, é isso que temos aqui agora.
‫Vamos também colocar A e B aqui.
‫B.
‫E, de fato, vamos fazer exatamente a mesma coisa aqui.
‫Então volte.
‫Devolva este também.
‫Então aqui, A e B também.
‫Então, isso de fato parece mais limpo para mim.
‫Agora temos A aqui e A
‫aqui novamente, mas, bem, não importa neste ponto.
‫Tudo bem.
‫Então volte aqui.
‫Volte aqui.
‫E antes que grite comigo, vamos remover isso.
‫E assim está melhor de novo.
‫Então coloque isso aqui.
‫E deve ser isso.
‫Tudo bem?
‫Vamos apenas por uma
‫questão de integridade copiar este comentário aqui também.
‫E então chame este de B novamente.
‫Tudo bem.
‫Perfeito.
‫Na verdade, vamos copiar este aqui também
‫para a função de desenvolvimento.
‫Porque agora, uma vez que enviarmos de volta
‫aquele erro, realmente não temos como ver o erro completo.
‫Tudo bem, então, se livrar disso para torná-lo mais visível.
‫E agora isso é lindo.
‫OK.
‫Então, vamos encerrar aqui
‫agora para que possamos iniciar nosso aplicativo de produção.
‫Basicamente, agora em produção.
‫E temos um script
‫para isso chamado npm run start production.
‫OK?
‫Então, se testarmos isso agora,
‫não devemos mais ver essa string aqui, lembra?
‫Porque, neste ponto, não temos nenhum tratamento de erros
‫para um nome de tour inválido como este.
‫OK?
‫Direito?
‫Já que
‫estamos em produção e não é um
‫erro operacional, bem, não queremos ver isso.
‫E isso é o que acabamos de codificar antes.
‫E, de fato, esta é a mensagem de erro mais genérica.
‫Direito?
‫Mas se colocarmos de volta aqui no controlador de visualizações, se colocarmos esse
‫tratamento de erro de volta, então
‫é claro, já que isso aqui agora
‫será um erro operacional, então, é claro, obteremos aquela
‫string de erro.
‫Porque é sempre
‫bom mostrar uma mensagem amigável ao usuário.
‫Mas, como você viu, isso realmente não aconteceu.
‫Então, por que isso?
‫Bem, estamos no erro de produção.
‫Estamos no site renderizado.
‫E, de fato, temos um erro operacional.
‫E entao ...
‫Nós temos isso no lugar.
‫E, de fato, deve funcionar como esperávamos.
‫Bem, vamos apenas tentar registrar no console a
‫mensagem do ponto de
‫erro apenas para ver se realmente a recebemos neste ponto.
‫Tudo bem.
‫Recarregue esse cara.
‫E aí está o erro.
‫Mesmo assim, isso é muito estranho.
‫Então, isso de fato registrou todo o erro.
‫Muito estranho.
‫Porque, por algum motivo, a mensagem também não está lá.
‫Então, vamos executá-lo novamente no desenvolvimento.
‫Então npm start.
‫Tudo bem.
‫E aqui, por algum motivo, ele obtém acesso a esta mensagem.
‫Isso significa que em nosso controlador de
‫visualizações, configuramos essa mensagem corretamente.
‫Execute-o novamente em produção.
‫Então esse é o tipo de coisa que não gostamos, certo?
‫Então, vamos dar uma olhada onde nosso erro na
‫produção é realmente criado.
‫E isso está aqui.
‫Então, esse objeto de erro que estamos usando aqui
‫na produção é uma cópia desse erro, certo?
‫Então, aquele que está entrando neste middleware.
‫E então vamos dar uma olhada em ambos no
‫console.
‫Portanto, mensagem de ponto de erro.
‫E então também mensagem de ponto de erro.
‫Então faça isso de novo.
‫OK.
‫Portanto, vemos esse erro,
‫aquele que está vindo direto para nossa função de
‫middleware, de fato tem a mensagem.
‫Mas então aquele que copiamos, então erro, por
‫algum motivo não.
‫E então esse truque que a gente tá
‫fazendo aqui, por algum motivo não copia a mensagem com ele,
‫tá bom?
‫E então vamos fazer uma correção rápida disso.
‫E digamos que a mensagem do ponto de erro seja igual à mensagem do ponto de erro.
‫Tudo bem?
‫E então isso deve consertar, espero.
‫Ah, certo.
‫Aqui vamos nós.
‫Direito.
‫Então agora você vê que eles são realmente os mesmos.
‫E esse era o problema.
‫Tudo bem?
‫Portanto, sem isso, na
‫verdade, todos os erros não funcionariam corretamente.
‫Então, se colocarmos isso aqui e tentarmos
‫fazer o login, por exemplo, admin @ natours. Io.
‫Então, você vê, também temos um erro indefinido aqui.
‫Tudo bem.
‫E isso é novamente porque estamos em
‫produção e nosso objeto de erro não copiou corretamente a mensagem.
‫Não tenho certeza por que não entendi
‫quando estávamos realmente implementando isso.
‫Mas talvez eu não o testei de forma completa o suficiente.
‫OK?
‫E, de qualquer forma, se
‫tentarmos isso agora, obteremos a mensagem de erro correta
‫que esperamos.
‫Tudo bem.
‫Excelente.
‫Então está resolvido.
‫E isso realmente encerra este vídeo.
‫Portanto, para
‫concluir, agora temos uma estratégia de
‫tratamento de erros que funciona para o desenvolvimento, como antes, e
‫também para a produção.
‫E então, em cada um deles, temos basicamente dois ramos.
‫Um envia a mensagem de erro para a
‫API, que é exatamente o que
‫tínhamos antes, e agora também temos uma espécie de manipulador
‫para o site renderizado.
‫E então, nesse caso, renderizamos nosso template de erro.
‫Em seguida, na produção, também
‫distinguimos entre website renderizado e API.
‫E então, como
‫antes, dentro de cada uma dessas
‫ramificações, também distinguimos entre os
‫erros de operação e os erros desconhecidos.
‫Tão operacional e desconhecido.
‫E depois renderizado por dentro, também operacional e desconhecido.
‫E então, para o site
‫renderizado, se tivermos um erro operacional, então confiável,
‫então enviamos nossa mensagem de erro confiável.
‫Mas, caso não confiemos no erro,
‫quando não o
‫soubermos, simplesmente enviaremos esta mensagem genérica de volta para o usuário.
‫Tão bom.
‫Vamos parar com isso aqui e voltar ao
‫desenvolvimento e encerrar esta palestra.
‫Então nos vemos no próximo.