关于ruby:如何通过一个救援声明尽快捕获所有异常

How to catch all exceptions as soon as they occur by just one rescue statement

我知道如何捕获异常,但我们所做的是在代码的可疑部分之后进行"救援"。 如果你有很多函数通过mysql2 gem向mysql发送查询并且想要捕获它们的异常,那该怎么办呢? 你可以做的一件事就是在每一个中都加上一个"救援"声明。 但我想通过一个救援声明来做到这一点。 所以我在代码的末尾放了一个"救援",并将所有代码放在"开始"和"结束"但是它没有用。

这是我的代码,你看到mysql查询中存在一个问题,只是因为"rescue"是文件的结尾,它没有捕获异常,但是当我把它放在那个查询之后就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    require 'mysql2'
require 'colored'

begin

def log(string)
  p"["+string.cyan+"]"
end

def err
  p"["+"FAIL".red+"]"
end

def done
  p"["+"DONE".red+"]"
end

class SqlClient
  def initialize()
    log"SqlClient/initialize"
    puts"Host:
"

    @host = gets.strip
    puts"User:
"

    @user = gets.strip
    puts"Pass:
"

    @pass = gets.strip
    @client = Mysql2::Client.new(host: @host , username: @user , password: @pass)

  end

  def list_databases()
    puts"We are listing your databases(not just projects)
 
 
"

    @client.query("ELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA").each do |row|
      p row["SCHEMA_NAME"]
    end

    puts"
 
 
"


  end

end

    rescue Mysql2::Error
    err
    abort

end


    `query': You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'ELECT SCHEMA_NAME FROM
INFORMATION_SCHEMA.SCHEMATA' at line 1 (Mysql2::Error)

我不是在找类似的东西:

1
2
3
4
5
begin
  # my code
rescue # this line is right after the code which is going to have problem and we catch it.

end

我在寻找这样的东西:

1
2
3
4
5
6
7
8
begin
  # first method
  # second method
  # thrid method
  # rest of code and etc ...
  # now this is end of file:
rescue
end

但正如你在我的代码中看到的,它没有用。

更新:我在这里发现了一个类似的问题,似乎没有答案:| 也许这是一种红宝石的弱点。


如果你想看到任何错误,只需使用e

1
2
3
4
5
6
7
8
9
begin
  # your call to a method of Mysql2 gem. for example:
  client = Mysql2::Client.new(:host =>"localhost", :username =>"root", etc...)

rescue => e
  puts e.message
  puts e.backtrace.inspect

end

为了捕获每个异常,您需要使用begin rescue end包装每个方法调用。当引发异常时,它会从执行中退出,因此它不会触及下一个方法。

为了捕捉所有错误,我想我会做这样的事情。请记住,这是丑陋的,我建议你不要这样做,但是...如果你想尝试,也许尝试这样的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
all_errors = []

# first method you call
begin
  # some error might happen here
  first_response = Mysql2::Client.new(:host =>"localhost", :username =>"root", etc...)
rescue => e
  all_errors << e
end

# second method you call
begin
  # some error might happen here
  second_response = Mysql2::Client.new(:host =>"localhost", :username =>"root", etc...)
rescue => e
  all_errors << e
end

puts all_errors.inspect

经过快速搜索后我发现:(http://coderrr.wordpress.com/2008/11/07/the-simple-way-to-print-exceptions-in-ruby/)

1
2
3
4
5
6
# catch all exceptions (anything that derives from Exception)
begin
  ...
rescue Exception
  puts $!, $@
end


你可以使用at_exit处理程序,它可以访问$中的最后一个异常!

喜欢

1
2
3
 at_exit {
   puts"the exception that killed us is", $!
 }

如果你想"一旦它们发生"就会捕获异常(而不是在它们被捕获之后)你可以使用ruby的"调试模式"(当它们出现在控制台时输出消息)或ruby-debug看看有没有办法在异常时启动Ruby调试器?


您是否尝试在班级中添加at_exit方法?这将允许您在ruby退出时执行某些操作。喜欢这篇文章。

Ruby at_exit

要么

来自Ruby 2.0 API Docs

但要注意从异常中巧妙地拯救!

当你试图找出你的代码在失败时没有失败的原因时,你会开始将你的头发拉下来(或另一个开发者)。我更喜欢用一个明亮的闪亮标志大量失败,说这里的代码失败了!呵呵。

祝好运!


似乎没有人注意到它,但是使用没有类的rescue会捕获所有StandardError,而且还有更多。

如果您想捕获所有需要执行的例外操作

1
2
3
4
5
6
7
begin
  # your code where you call SqlClient.new etc
rescue Exception => e
  puts"error raised"
  puts [e, e.backtrace].flatten.join("
"
)
end

所有错误类的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Exception
 NoMemoryError
 ScriptError
   LoadError
   NotImplementedError
   SyntaxError
 SignalException
   Interrupt
 StandardError
   ArgumentError
   IOError
     EOFError
   IndexError
   LocalJumpError
   NameError
     NoMethodError
   RangeError
     FloatDomainError
   RegexpError
   RuntimeError
   SecurityError
   SystemCallError
   SystemStackError
   ThreadError
   TypeError
   ZeroDivisionError
 SystemExit
 fatal


只需将所有代码包装在:

1
2
3
4
5
6
7
begin

   #yourcode
   #as much as you want
rescue

end