Handling your Exceptions


Gerenciar exceptions com o Ruby on Rails é bem simples. Atualmente exceptions 404 (not found) e 500 (internal server error) tem um arquivo html na pasta public, quando uma dessas exceptions acontece, de acordo com o http status o rails renderiza o html correspondente.

Outras abordagens

Em alguns casos precisamos ir mais a fundo nessa abordagem do rails, somente editar o html não é o que necessitamos em alguns casos. Mas não vou entrar nesses detalhes por hora, minha questão é quando estamos trabalhando com uma API.

Imagine comigo que estamos recebendo e enviando JSON, o usuário envia uma requisição com um JSON e o servidor responde com outro JSON. Digamos que aconteça alguma falha no servidor, algum registo inconsistente na base que não foi migrado corretamente, algo que tenhamos um erro com status 500 (quando um exception qualquer é lançada e não foi tratada), obviamente, o body da sua resposta, será exatamente o conteudo html da página 500, se por um acaso, o cliente tentar consumir esse “JSON”, ele vai ver algum erro informando que o conteúdo não é um JSON válido.

Dentro do ActiveSupport temos o módulo Rescuable, contem um pequeno método chamado rescue_from, o uso dele é simples:

rescue_from Exception, :with => :some_method

onde o primeiro argumento pode ser uma ou mais exceptions, e a opção with é um método responsável por gerenciar essa requisição.

em outras palavras, quando a Exception acontecer o rails vai chamar some_method para identificar o que fazer com essa exception.

Tratando requisições a API

Quando se está trabalhando somente com JSON, enviando e recebendo, é necessário fazer alguns ajustes pra garantir que a resposta será um JSON, mesmo em um bug do software, que seria normalmente uma resposta 500 ao cliente.

Tratar isso no rails é bem simples

class ApplicationController < ActionController::Base
  respond_to :json
  
  rescue_from Exception, :with => :render_internal_error
  
  private
  
  def render_internal_error(exception)
    render :json => { :errors => ["erro de processamento interno"] }, :status => :internal_server_error 
  end
end

dessa forma nosso usuário vai ter uma mensagem, que ainda não é legal de se receber, mas não vai receber um HTML pra fazer parser, e o status continua sendo 500 usando o symbol :internal_server_error.

para ver mais desses symbols nas respostas do rails da uma olhada aqui

Você também pode tratar exceptions como ActiveRecord::RecordNotFound, para mostrar uma mensagem mais amigavél. Da forma que foi mostrado aqui, estou capturando uma exception genérica, evite esse tipo de abordagem, use as exceptions expecíficas do seu problema, e deixe a generalização em ultimo caso.

até a próxima.

blog comments powered by Disqus