Habilite rapidamente o tratamento de exceção personalizado baseado em middleware no Rails

Sempre fiquei insatisfeito com o uso rescue_fromde meu ApplicationController para lidar com as várias exceções significativas em meu aplicativo. Sempre pareceu mais uma solução para tipos individuais de exceções, em oposição a uma solução ampla para cobrir todas as exceções não detectadas com páginas de erro personalizadas. A maioria da documentação e artigos de ajuda sobre o assunto apenas recomendam o uso de rescue_frompáginas de erro não padronizadas ( exemplo ). Mas o middleware do Rails já possui ferramentas para traduzir exceções não capturadas no código do seu aplicativo para a resposta de erro correta , e uma forma estereotipada para qualquer aplicativo fornecer respostas com base no código de status.

O ActionDispatch :: ShowException middleware contém uma referência a um aplicativo Rack que irá responder a erros usando os caminhos com base no código de status: /400, /404, /500, ou etc. O aplicativo padrão é o ActionDispatch :: PublicExceptions classe que simplesmente leva a url e tentativas para retornar a página public/<error_code>.html. Qualquer aplicativo Rack que responda a essas rotas pode ser usado, no entanto, é apenas uma questão de configuração.

O aplicativo atribuído para lidar com a renderização da página de erro pode ser definido em sua configuração tão facilmente quanto este:

config / application.rb:

config.exceptions_app = self.routes

Nesse caso, o middleware está sendo instruído a usar seu aplicativo atual para renderizar páginas. Quando uma exceção for resgatada, ela chamará o exceptions_appusando o código de erro como caminho, então você desejará criar rotas e pelo menos um controlador para tratá-las.

config / routes.rb:

match "/400", :to => "errors#bad_request"
match
"/404", :to => "errors#not_found"
match
"/500", :to => "errors#internal_server_error"

Devem ser matchdiretivas, não verbos individuais, pois essas rotas precisarão corresponder a qualquer tipo de solicitação que encontre um erro.

app / controllers / errors_controller.rb:

def bad_request
end

def not_found
end

def internal_server_error
end

No controlador, você pode fazer o que for necessário em cada uma dessas ações. No entanto, tenha cuidado aqui, pois quaisquer erros levantados não serão detectados e exibidos da maneira padrão, uma vez que ActionDispatch :: ShowException espera poder retornar o que chama de ” resposta à prova de falhas “.

Isso fornece uma abordagem baseada na configuração de middleware para lidar com erros onde mais do que simples páginas estáticas são necessárias. Forneça cobertura para quantos códigos de erro você achar necessário, e é recomendado usar um catchall baseado em regexp em suas rotas para liberar qualquer código de erro para o qual você não tenha uma página personalizada para uma ação de erro catchall (ou responder com “X- Cascade: passe “cabeçalho como PublicExceptions faz):

get '/:code', to: 'errors#catch_all', constraints: {code: /^d{3}$/}

Uma abordagem modular também consiste em construir suas páginas de erro personalizadas como um aplicativo independente do aplicativo principal. Como mencionado, qualquer app Rack que responde às rotas como , , , ou etc pode ser usado. Aqui está um exemplo (graças a @lazylester) de como fazer isso./400/404/500

Para mim, rescue_fromparece mais um hack, enquanto o middleware que roteia a renderização da página de erro através dos controladores e visualizações do meu aplicativo usando rotas estereotipadas parece muito mais integrado e congruente com o ciclo de vida das solicitações do Rails.

Mais informações: