Express: Entendendo o tratamento de erros em Express

Image for post
Image for post

Foi difícil aprender a lidar com erros no Express. Ninguém parecia ter escrito as respostas que eu precisava, então tive que aprender da maneira mais difícil.

Hoje, quero compartilhar tudo o que sei sobre como lidar com erros em um aplicativo Express.

Vamos começar com erros síncronos.

Manipulando Erros Síncronos

Se você deseja criar um erro síncrono, você pode usar throw em um manipulador de solicitação no Express (nota: manipuladores de solicitações, request handlers, também são chamados de controladores, controllers. Prefiro chamar de manipuladores de solicitações porque fica mais explícitos e fácil de entender).

Esses erros podem ser detectados com um manipulador de erros. Se você não escreveu um manipulador de erros customizado (mais sobre isso abaixo), o Express tratará o erro para você com um manipulador de erros padrão.

O manipulador de erros padrão do Express:

  1. Defina o status HTTP como 500
  2. Envia uma resposta de texto ao solicitante
  3. Registra a resposta de texto no console
Image for post
Image for post

Manipulando Erros Assíncronos

Se você deseja manipular um erro assíncrono, é necessário enviar o erro para um manipulador de erro do Express por meio do argumento next:

Image for post
Image for post

Se você estiver usando o async..await em um aplicativo Express, eu recomendo usar o express-async-handler. Isso permite escrever código assíncrono sem blocos try..catch. Falei mais sobre isso em "Usando o async/await no Express".

Ao usar o manipulador de solicitações express-async-handler, você pode criar um erro como antes, usando throw, e ele será tratado com um manipulador de erros Express.

Image for post
Image for post

Escrevendo um manipulador de erro personalizado

Os manipuladores de erro expressos recebem quatro argumentos:

  1. error
  2. req
  3. res
  4. next

Eles devem ser colocados após todos os seus middlewares e rotas:

O Express deixará de usar seu manipulador de erros padrão depois que você criar um manipulador de erros personalizado. Para lidar com um erro, você precisa se comunicar com o frontend que está fazendo a solicitação. Isso significa que você precisa:

  1. Enviar um código de status HTTP válido
  2. Enviar uma resposta válida

Um código de status HTTP válido depende do que aconteceu. Aqui está uma lista de erros comuns para os quais você deve se preparar:

400 Bad Request Error — Usado quando o usuário falha ao incluir um campo (como nenhuma informação do cartão de crédito em uma forma de pagamento) — Também é usado quando o usuário digita informações incorretas (exemplo: digitando senhas diferentes em um campo de senha e campo de confirmação de senha).

401 Unauthorized Error — Usado quando o usuário digita informações de login incorretas (como nome de usuário, email ou senha).

403 Forbidden Error — Usado quando o usuário não tem permissão para acessar o endereço.

404 Not Found Error — Usado quando o endereço não pode ser encontrado.

500 Internal Server Error — A solicitação enviada pelo front-end está correta, mas ocorreu um erro no back-end.

Depois de determinar o código de status HTTP correto, você deseja definir o status com res.status:

O código de status HTTP deve corresponder à mensagem de erro. Para que o código de status corresponda à mensagem de erro, você deve enviar o código de status junto com o erro.

A maneira mais fácil é usar o pacote http-errors. Permite enviar três coisas em seus erros:

  1. Um código de status
  2. Uma mensagem para acompanhar o erro
  3. Quaisquer propriedades que você gostaria de enviar (isso é opcional).

Instalando o http-errors:

Usando o http-errors:

Vamos montar um exemplo para torná-lo mais claro. Digamos que você tentou encontrar um usuário pelo endereço de e-mail. O usuário não pode ser encontrado. Você deseja lançar um erro que diz “Usuário não encontrado”.

Ao criar o erro, você deseja:

  1. Enviar um error 400 Bad Request Error (porque o usuário preencheu informações incorretas). Você envia isso como o primeiro parâmetro.
  2. Enviar uma mensagem dizendo “Usuário não encontrado”. Você envia isso como o segundo parâmetro.

Você pode obter o código de status com error.status e a mensagem de error com error.message.

Image for post
Image for post

Em seguida, defina o status do erro com res.status. Você envia a mensagem com res.json.

Pessoalmente, gosto de enviar o status, a mensagem e o rastreamento do erro para que eu possa depurar facilmente.

Código de status de fallback

Se o erro não for criado com createError, ele não terá uma propriedade de status.

Aqui está um exemplo. Digamos que você tentou ler um arquivo com fs.readFile, mas o arquivo não existe.

Este erro não conteria uma propriedade status.

Image for post
Image for post

Nesses casos, você pode usar o padrão 500 Internal Server Error.

Alterando o código de status de um erro

Digamos que você deseja buscar um arquivo baseado na informação enviada por um usuário. Se o arquivo não existir, você deverá lançar um 400 Bad Request Error, porque não é culpa do seu servidor.

Nesse caso, você deseja usar try..catch para capturar o erro original. Em seguida, você recria um erro com createError.

Manipulando erros 404

Um terminal não será encontrado se uma solicitação cair em todos os seus middlewares e rotas.

Para lidar com um erro não encontrado, insira um middleware entre suas rotas e seu manipulador de erros. Aqui, crie um erro com createError.

Image for post
Image for post

Detalhes sobre “Cannot set headers after they are sent to the client”

Não entre em pânico se você vir um erro que diz "Cannot set headers after they are sent to the client".

Este erro ocorre porque o código executou métodos que definem cabeçalhos de resposta mais de uma vez no mesmo manipulador. Estes são os métodos que definem os cabeçalhos de resposta para você:

  1. res.send
  2. res.json
  3. res.render
  4. res.sendFile
  5. res.sendStatus
  6. res.end
  7. res.redirect

Por exemplo, se você executar res.render e res.json no mesmo manipulador de respostas, voc6e receberá o erro.

Portanto, se você receber esse erro, verifique seus manipuladores de resposta para que ele não execute os métodos acima duas vezes.

Cuidados ao fazer streaming

Se ocorrer um erro ao realizar streaming de uma resposta ao front-end, você receberá o mesmo erro “Cannot set headers…”.

Nesse caso, o Express declara que você deve delegar o tratamento de erros aos manipuladores padrões do Express. Isso enviará um erro e fechará a conexão para você.

Créditos

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store