2017-01-31 6 views
1

Это на самом деле 3 часть вопроса:Как спасти психические исключения Ямла?

  1. Что все исключения Psych броски?
  2. Как вы узнаете, какие они есть, когда документация не докучает их перечислить?
  3. Пример кода, чтобы поймать все возможные исключения YAML.load_file?

Я бы не просил, не 3, но этот вопрос предполагает я встречу странные вопросы: Can't rescue YAML.load exception

Основываясь на этом вопросе How to know what exceptions to rescue

я получил:

Psych::Exception 
     Psych::BadAlias 
     Psych::DisallowedClass 
     Psych::SyntaxError 

Но когда я пытаюсь поймать этот код, все еще не удается

irb(main):002:0> begin 
irb(main):003:1* YAML.load_file('test_file_does_not_exist') 
irb(main):004:1> rescue Psych::Exception 
irb(main):005:1> puts $!.message 
irb(main):006:1> end 
Errno::ENOENT: No such file or directory @ rb_sysopen - test 
    from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `initialize' 
    from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `open' 
    from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `load_file' 
    from (irb):3 
    from /home/marko/.rubies/ruby-2.3.1/bin/irb:11:in `<main>' 

Я ищу способы поймать всю эту ерунду. Независимо от причины сбоя, я хочу поймать его и отобразить сообщение, прежде чем оно вернется к основному коду обработки исключений.

Microsoft, который мне не особенно нравится, показывает все исключения для каждого класса, который они когда-либо писали. Пример: https://msdn.microsoft.com/en-us/library/b9skfh7s(v=vs.110).aspx

ответ

2

Psych исключения

Один из способов проверить, будет:

exceptions_before = ObjectSpace.each_object(Class).select{|klass| klass < Exception} 
require 'yaml' 
exceptions_after = ObjectSpace.each_object(Class).select{|klass| klass < Exception} 

Это может пропустить исключения, генерируемые динамически. Тем не менее, здесь разница между 2 и их предки:

(exceptions_after - exceptions_before).each do |yaml_exception| 
    p yaml_exception.ancestors 
end 

# [Psych::SyntaxError, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject] 
# [Psych::DisallowedClass, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject] 
# [Psych::BadAlias, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject] 
# [Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject] 
# [StringScanner::Error, StandardError, Exception, Object, Kernel, BasicObject] 

Кажется, что Psych::Exception и StringScanner::Error охватывают все исключения брошены Psych.

Прочие исключения

Все может пойти не так, как надо. Тем не менее, наиболее распространенное исключение будет:

Errno::ENOENT 

если ваш .yml не найден. Вы можете либо спасти исключение, либо просто проверить, что File.exist? перед чтением файла yaml.

ИМХО, вы не должны пытаться спасать каждое исключение.

Несмотря на то, что похоже, что вы ищете rescue => e или даже rescue Exception => e, это not a good idea.

+0

Перейти к редактированию вопроса –

+0

Как насчет ERRNO :: SOMETHING, когда вы 'YAML.load_file', которого не существует? –

+0

Как насчет ошибки sytax, когда вы не закрываете кавычки вокруг строки имени файла? :) В принципе, все может пойти не так, как надо, при загрузке файла. Я понял этот вопрос как относящийся к конкретным исключениям для Психотерапии. –