Como eu levanto uma exceção no Rails para que ela se comporte como outras exceções do Rails?


91

Eu gostaria de levantar uma exceção para que ele faça a mesma coisa que uma exceção normal do Rails faz. Em especial, mostre a exceção e o rastreamento de pilha no modo de desenvolvimento e mostre a página "Desculpe, mas algo deu errado" no modo de produção.

Tentei o seguinte:

raise "safety_care group missing!" if group.nil?

Mas ele simplesmente grava "ERROR signing up, group missing!"no arquivo development.log


2
a mensagem de erro que você postou não parece vir dessa exceção (é uma mensagem diferente) é realmente isso que você está vendo?
— levinalex

Respostas:


139

Você não precisa fazer nada de especial, deve apenas funcionar.

Quando eu tiver um aplicativo Rails novo com este controlador:

class FooController < ApplicationController
  def index
    raise "error"
  end
end

e vai para http://127.0.0.1:3000/foo/

Estou vendo a exceção com um rastreamento de pilha.

Você pode não ver todo o stacktrace no log do console porque o Rails (desde 2.3) filtra as linhas do stack trace que vêm do próprio framework.

Veja config/initializers/backtrace_silencers.rbno seu projeto Rails


2
Excelente resposta concisa.
— rcd

1
O link skitch (vendo a exceção com um rastreamento de pilha) não está mais funcionando
— Asaf de

@levinalex isso será seguro no modo de produção para mostrar o stacktrace?
— BKSpurgeon

@levinalex - obrigado alex. existe alguma maneira de adicionar uma string personalizada à mensagem de erro?
— BKSpurgeon

62

Você pode fazer assim:

class UsersController < ApplicationController
  ## Exception Handling
  class NotActivated < StandardError
  end

  rescue_from NotActivated, :with => :not_activated

  def not_activated(exception)
    flash[:notice] = "This user is not activated."
    Event.new_event "Exception: #{exception.message}", current_user, request.remote_ip
    redirect_to "/"
  end

  def show
      // Do something that fails..
      raise NotActivated unless @user.is_activated?
  end
end

O que você está fazendo aqui é criar uma classe "NotActivated" que servirá como Exception. Usando aumento, você pode lançar "NotActivated" como uma exceção. rescue_from é a maneira de capturar uma Exceção com um método especificado (not_activated neste caso). Um exemplo bem longo, mas deve mostrar como funciona.

Muitas felicidades,
Fabian


Isso não mostra a exceção e o rastreamento de pilha no modo de desenvolvimento e mostra a página "Desculpe, mas algo deu errado" no modo de produção.
— Chirag Patel

2
A página "desculpe" é, na verdade, o manipulador de erros 500 do seu servidor da web. Verifique seu arquivo .htaccess e normalmente você o verá lá
— Jeff Paquette

Talvez não seja uma resposta ao OP, mas um exemplo muito útil, obrigado!
— Neil Stockbridge

11

Se você precisa de uma maneira mais fácil de fazer isso e não quer muito barulho, uma execução simples pode ser:

raise Exception.new('something bad happened!')

Isso levantará uma exceção, digamos ecome.message = something bad happened!

e então você pode resgatá-lo como está resgatando todas as outras exceções em geral.


Não é uma boa ideia levantar ou resgatar 'Exception' em si, tente usar StandardError ao invés. Veja mais detalhes: stackoverflow.com/questions/10048173/…
— Ekamjit Singh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.