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 |
但正如你在我的代码中看到的,它没有用。
更新:我在这里发现了一个类似的问题,似乎没有答案:| 也许这是一种红宝石的弱点。
如果你想看到任何错误,只需使用
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 |
为了捕获每个异常,您需要使用
为了捕捉所有错误,我想我会做这样的事情。请记住,这是丑陋的,我建议你不要这样做,但是...如果你想尝试,也许尝试这样的事情:
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
但要注意从异常中巧妙地拯救!
当你试图找出你的代码在失败时没有失败的原因时,你会开始将你的头发拉下来(或另一个开发者)。我更喜欢用一个明亮的闪亮标志大量失败,说这里的代码失败了!呵呵。
祝好运!
似乎没有人注意到它,但是使用没有类的
如果您想捕获所有需要执行的例外操作
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 |