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: