3

我知道如何捕捉异常,但我们所做的是将“救援”放在代码的可疑部分之后。如果你有很多函数通过 mysql2 gem 向 mysql 发送查询,并且你想捕获它们的异常。您可以做的一件事是在每个文件中添加“救援”声明。但我只想通过一份救援声明来做到这一点。所以我在代码末尾放了一个“救援”,并将所有代码放在“开始”和“结束”中,但它没有用。

这是我的代码,正如您所见,mysql 查询中存在问题,仅仅因为“rescue”是文件的结尾,它没有捕获异常,但是当我将它放在该查询之后它可以工作。

    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: \n"
    @host = gets.strip
    puts "User: \n"
    @user = gets.strip
    puts "Pass: \n"
    @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) \n \n \n "
    @client.query("ELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA").each do |row|
      p row["SCHEMA_NAME"]
    end

    puts "\n \n \n"

  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)

我不是在寻找类似的东西:

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

end

我正在寻找这样的东西:

begin
  # first method
  # second method
  # thrid method
  # rest of code and etc ...
  # now this is end of file: 
rescue
end

但正如您在我的代码中看到的那样,它不起作用。

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

4

5 回答 5

4

如果您想查看任何错误,请使用e例如

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. 当引发异常时,它会退出执行,因此它不会命中下一个方法。

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

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/

# catch all exceptions (anything that derives from Exception)
begin
  ...
rescue Exception
  puts $!, $@
end
于 2013-03-06T23:55:53.480 回答
2

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

喜欢

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

如果您想在“一旦发生”(而不是在它们被捕获后)捕获异常,您可以使用 ruby​​ 的“调试模式”(当它们发生到控制台时输出消息)或 ruby​​-debug 请参阅Is there any way to异常时启动 Ruby 调试器?

于 2013-03-07T00:15:53.353 回答
0

似乎没有人注意到它,但rescue不使用类将捕获所有 StandardError 并且还有更多。

如果你想捕获所有你需要做的异常

begin
  # your code where you call SqlClient.new etc
rescue Exception => e
  puts "error raised"
  puts [e, e.backtrace].flatten.join("\n")
end

所有错误类别的列表:

例外
 无内存错误
 脚本错误
   加载错误
   未实现错误
   语法错误
 信号异常
   打断
 标准错误
   参数错误
   IO错误
     EOF错误
   索引错误
   本地跳转错误
   名称错误
     无方法错误
   范围错误
     浮动域错误
   正则表达式错误
   运行时错误
   安全错误
   系统调用错误
   系统堆栈错误
   线程错误
   类型错误
   零除法错误
 系统退出
 致命的
于 2013-03-07T00:08:00.900 回答
0

只需将所有代码包装在:

begin

   #yourcode
   #as much as you want
rescue 

end 
于 2013-03-06T23:50:36.557 回答
0

你试过在你的课堂上添加一个 at_exit 方法吗?这将允许您在 ruby​​ 退出时做一些事情。就像在这篇文章中一样。

Ruby at_exit

或者

来自 Ruby 2.0 API 文档

但是要小心巧妙地从异常中拯救!

当您试图弄清楚为什么您的代码在应该失败时没有失败时,您将开始在路上(或其他开发人员会)拉出您的头发。我更喜欢用明亮的闪亮标志大量失败,说明代码在这里失败!呵呵。

祝你好运!

于 2013-03-07T00:17:59.830 回答