web-dev-qa-db-fra.com

Passer plusieurs classes d'erreur à la clause de secours de Ruby de manière DRY

J'ai du code qui doit récupérer plusieurs types d'exceptions dans Ruby:

begin
  a = Rand
  if a > 0.5
    raise FooException
  else
    raise BarException
  end
rescue FooException, BarException
  puts "rescued!"
end

Ce que j'aimerais faire, c'est en quelque sorte stocker la liste des types d'exceptions que je veux récupérer quelque part et passer ces types à la clause de sauvetage:

EXCEPTIONS = [FooException, BarException]

et alors:

rescue EXCEPTIONS

Est-ce même possible, et est-ce possible sans quelques appels vraiment hack-y à eval? Je n'ai pas d'espoir étant donné que je vois TypeError: class or module required for rescue clause lorsque j'essaie ce qui précède.

91
apb

Je viens de rencontrer ce problème et j'ai trouvé une autre solution. Dans le cas où vos FooException et BarException seront tous des classes d'exceptions personnalisées et en particulier si elles sont toutes liées par thème, vous pouvez structurer votre hiérarchie d'héritage de manière à ce qu'elles héritent toutes du même parent classe, puis sauver uniquement la classe parent.

Par exemple, j'ai eu trois exceptions: FileNamesMissingError, InputFileMissingError et OutputDirectoryError que je voulais sauver avec une seule instruction. J'ai créé une autre classe d'exceptions appelée FileLoadError, puis j'ai configuré les trois exceptions ci-dessus pour en hériter. J'ai ensuite sauvé seulement FileLoadError.

Comme ça:

class FileLoadError < StandardError
end

class FileNamesMissingError < FileLoadError
end

class InputFileMissingError < FileLoadError
end

class OutputDirectoryError < FileLoadError
end

[FileNamesMissingError,
 InputFileMissingError,
 OutputDirectoryError].each do |error| 
   begin  
     raise error
   rescue FileLoadError => e
     puts "Rescuing #{e.class}."
   end 
end
1
Mikhail Golubitsky