2010-08-01 12 views
32

È possibile creare una sottoclasse di un'eccezione per renderla più descrittiva, ma come si dovrebbe impostare il 'messaggio' predefinito?Classi di errore di eccezione di Ruby

class MyError < StandardError 
    # default message = "You've triggered a MyError" 
end 

begin 
    raise MyError, "A custom message" 
rescue Exception => e 
    p e.message 
end 

begin 
    raise MyError 
raise Exception => e 
    p e.message 
end 

Il primo dovrebbe uscita 'Un messaggio personalizzato'

Il secondo dovrebbe uscita 'Hai scatenato una MyError'

eventuali suggerimenti riguardo a migliori pratiche?

risposta

57

Definire un metodo di inizializzazione, che accetta il messaggio come argomento con un valore predefinito. Quindi chiamare il metodo di inizializzazione StandardError con quel messaggio (utilizzando super).

class MyError < StandardError 
    def initialize(msg = "You've triggered a MyError") 
    super(msg) 
    end 
end 
+29

Solo "super" è sufficiente. Se chiami 'super' senza un elenco di argomenti, passerà semplicemente tutti gli argomenti, che è il motivo per cui, quando in realtà vuoi passare argomenti * no *, devi chiamare esplicitamente' super() '. –

+0

@ JörgWMittag Perché tutte le classi di errore personalizzate ereditano da "StandardError"? Qualche ragione dietro? –

+0

@ArupRakshit Perché è sicuro. Ogni volta che si salvano dagli errori dovrebbe essere un "Errore Standard" (o inferiore), poiché errori di livello superiore come "Eccezione" possono anche essere lanciati quando si colpisce CTL-C, ecc. Vedi questo per maggiori informazioni http://rails-bestpractices.com/post/2012/11/01/don-t-rescue-exception-rescue-standarderror – Sean

1

Si può anche sovrascrivere il metodo message nella sottoclasse e restituire la stringa che desideri venga visualizzato. Preferisco questo dato che sembra mantenere le cose un po 'più pulite se vuoi fare qualcosa di interessante prima di visualizzare il messaggio.

class CustomError < StandardError 

    def initialize(error_code, error_info) 
    @code, @info = error_code, error_info 
    end 

    def message 
    "<Code: #{@code}> <Info: #{@info}>" 
    end 

end 
Problemi correlati