Che tipo di eccezione per chiedere argomenti fuori intervallo?

5

Che tipo di eccezione dovrei gettare?

Ho una classe di console che descrive il rettangolo di celle che un utente può indicizzare passando in una coordinata:

width, height = 80, 25
console = Console.new(width, height)

x, y = 2, 5
point_on_screen = Point.new(x, y)
console[point_on_screen] = 'a'

Ora mi sto chiedendo quali tipi di eccezione generare quando un indice si verifica fuori limite. Cioè, al di fuori dei domini (costante!) X: [0, larghezza] e y: [0, altezza]. Potrei lanciare un RangeError o un ArgumentError * .

  1. Importa il tipo di eccezione da lanciare finché il messaggio di errore è utile?
  2. Devo usare lo stesso tipo di eccezione sia per la costruzione della console che per l'indicizzazione? I due sono veramente semanticamente diversi?

* restituire un tipo di oggetto fuori dai limiti è probabilmente un'opzione migliore - qualcosa come un modello di oggetto nullo - ma non è quello che mi sto chiedendo qui.

ArgumentError

Un'opzione è lanciare un ArgumentError perché l'argomento è ovviamente sbagliato, le dimensioni non possono mai essere non negative. Questo è ciò che lancio nell'esempio 1, perché dovremmo sapere in anticipo che le dimensioni devono essere non negative.

Esempio 1:

console = Console new(-3, 4) # Argument error

RangeError

Un'altra opzione è lanciare un RangeError perché l'argomento è fuori dall'intervallo valido. Li uso per l'indicizzazione. L'argomento è sempre fuori intervallo se x < 0, ma se x ≥ 0 dipende dalla larghezza della console se x è nel dominio.

Esempio 2:

console = Console.new(20, 40)
pt = Point.new(-3, 4)
Console[pt] # RangeError
    
posta R. Peereboom 09.07.2014 - 17:06
fonte

2 risposte

5

Does it matter which type of exception to throw as long as the error message is useful?

In casi come questo, spesso rimando ai documenti ufficiali per le definizioni e esempi di utilizzo.

I documenti per RangeError sono un po 'concisi:

RangeError
Raised when a given numerical value is out of range.

[1, 2, 3].drop(1 << 100)
raises the exception:
RangeError: bignum too big to convert into long

E anche se i documenti per ArgumentError implicano un incoraggiamento verso un% più specifico di co_de, uno degli esempi (in grassetto sotto) sembra certamente una potenziale corrispondenza per il tuo caso d'uso:

ArgumentError
Raised when the arguments are wrong and there isn't a more specific Exception class.

Ex: passing the wrong number of arguments
[1, 2, 3].first(4, 5)
raises the exception:
ArgumentError: wrong number of arguments (2 for 1)

Ex: passing an argument that is not acceptable:
[1, 2, 3].first(-4)
raises the exception:
ArgumentError: negative array size

In generale, le eccezioni Exception -type sono un modo chiaro e prevedibile per comunicare al chiamante che hanno fornito alcuni parametri non validi.

Riguardo alla tua menzione di " ... finché il messaggio è utile ... ", io dico di si, assolutamente. Cerca sempre di includere un messaggio significativo quando segnali un errore.

Per quanto riguarda l'alternativa null object: Personalmente, ti incoraggio ad aumentare esplicitamente l'errore piuttosto che restituire un oggetto nullo (o qualche altro indicatore fuori limite). Il codice creato con questo modello è tormentato da controlli nulli costanti e inevitabilmente un oggetto nullo sfuggirà alle tue reti di sicurezza e causerà il caos inaspettato sul tuo programma.

Quando lavoro con un software che restituisce normalmente valori nulli o valori speciali come un indicatore "qualcosa è andato storto", devo passare altri cicli mentali per assicurarmi di controllare tutte le risposte e che sto cercando i giusti flag di errore. (Ma la convenzione è certamente un fattore, quindi se stai lavorando con una base di codice esistente che utilizza il modello di oggetto nullo, potrebbe essere meglio continuare.)

Ecco qualche buona lettura aggiuntiva sulle eccezioni rispetto alle variabili di errore: Le variabili di errore sono un anti-pattern o un buon design?

    
risposta data 09.07.2014 - 19:26
fonte
0

Potresti sempre creare un'eccezione personalizzata se non trovi le eccezioni che hai a disposizione correttamente.

class MyUsefulException < Exception
end

raise MyUsefulException, 'Huzzah, my exception lives!!!'
    
risposta data 11.07.2014 - 22:31
fonte

Leggi altre domande sui tag