Ruby的新手 - 我已经看过一些似乎相似的问题的答案,但说实话,我无法理解他们。
我有一些代码可以读取.csv文件。数据被分成每个用户记录40-50行的组,并根据通过网站访问的数据库验证行中的数据。
每条记录都需要登录,但是一旦该用户登录了.csv文件中的每一行,就可以检查到达下一个用户,此时用户退出。
但是,如果发生错误(例如,网站上的结果与.csv文件上的预期结果不同),程序将停止工作。
我需要的东西会 a)告诉我文件中哪一行发生了错误 b)在完成运行时记录要输出的行,并且 iii)从.csv文件的下一行重启程序
我到目前为止的代码是
提前致谢,
彼得
require 'csv-mapper'
loginrequired = true
Given(/^I compare the User Details from rows "(.*?)" to "(.*?)"$/) do |firstrow, lastrow|
data = CsvMapper.import('C:/auto_test_data/User Data csv.csv') do
[dln, nino, pcode, endor_cd, ct_cd]
end
#Row number changed because Excel starts at 'row 1' and Ruby starts counting at 'row 0'
(firstrow.to_i-1..lastrow.to_i-1).each do |row|
@licnum1 = data.at(row).dln
@licnum2 = data.at(row+1).dln
@nino = data.at(row).nino
@postcode = data.at(row).pcode
@endor_cd = data.at(row).endor_cd
@ct_cd = data.at(row).ct_cd
#Login only required once for each new user-account
if
loginrequired == true
logon_to_vdr #def for this is in hooks
click_on 'P and D'
loginrequired = false
end
#This is the check against the database and is required for every line in the .csv file
check_ctcd #def for this is in hooks
#Need something in here to log errors and move on to the next line in the .csv file
#Compare the ID for the next record and logout if they're different
if @licnum1 == @licnum2
loginrequired = false
else
loginrequired = true`enter code here`
click_on 'Logout'
end
end
end
答案 0 :(得分:1)
您似乎需要一些错误记录,因为您显然不知道您接收的错误类型或位置。如果此脚本是独立的,您可以将$stderr
重定向到文件,以便您可以阅读出错的地方。
# put this line at the top of your script
$stderr = File.open("/path/to/your/logfile.log","a")
当发生错误时,ruby会自动将错误消息,类和回溯写入您指定的日志文件,以便您可以追溯事情未按预期进行的行。 (当您从命令行运行脚本时,通常此信息将在发生错误时脱口回到终端。)
例如,在我的桌面上,我创建了一个文件log_stderr.rb,其中包含以下内容(包括行号):
1 $stderr = File.open("C:/Users/me/Desktop/my_log.log","w")
2
3 #require a file which will raise an error to see the backtrace
4 require_relative 'raise_error.rb'
5
6 puts "code that will never be reached"
同样在我的桌面上,我使用以下内容创建了raise_error.rb文件(以加深回溯以获得更好的示例输出):
1 # call raise to generate an error arbitrarily
2 # to halt execution and exit the program.
3 raise RuntimeError, 'the program stopped working!'
当我从命令行运行ruby log_stderr.rb
时,my_log.log在我的桌面上创建,其中包含以下内容:
C:/Users/me/Desktop/raise_error.rb:3:in `<top (required)>': the program stopped working! (RuntimeError)
from C:/Users/me/Desktop/log_stderr.rb:4:in `require_relative'
from C:/Users/me/Desktop/log_stderr.rb:4:in `<main>'
如果您在更大的环境中工作,在其他脚本中调用脚本,那么您可能不希望重定向$stderr
,因为这会影响环境中运行的所有其他内容。 ($stderr
是全局的,如$
变量前缀所示。)如果是这种情况,您可能希望实现begin; rescue; end
结构并创建自己的日志文件,这样就不会影响$stderr
。
同样,由于你不知道错误发生在哪里,你想用begin; end
# at the very top of the script, begin watching for weirdness
begin
logfile = File.open("/path/to/your/logfile.log", "w")
require 'csv-mapper'
#. . .
# rescue and end at the very bottom to capture any errors that have happened
rescue => e
# capture details about the error in your logfile
logfile.puts "ERROR:", e.class, e.message, e.backtrace
# pass the error along since you don't know what it is
# and there may have been a very good reason to stop the program
raise e
end
如果您发现错误仅在阻止(firstrow.to_i-1..lastrow.to_i-1).each do |row|
中发生,您可以将begin; end
置于此阻止内部以访问本地row
变量,或者创建一个顶级变量独立于块,并在块的每次迭代期间分配它以报告给您的日志文件:
begin
logfile = File.open("/path/to/your/logfile.log", "w")
csv_row = "before csv"
#. . .
(firstrow.to_i-1..lastrow.to_i-1).each do |row|
csv_row = row
#. . .
end
csv_row = "after csv"
rescue => e
logfile.puts "ERROR AT ROW: #{csv_row}", e.class, e.message, e.backtrace
raise e
end
我希望这有帮助!
答案 1 :(得分:0)
这似乎不需要在这里拯救异常。但你可以做的是check_ctcd
方法,如果记录不匹配则引发错误。然后你可以从中拯救它。为了知道它是哪一行,在迭代中,你可以使用#each_with_index
并在出现问题时记录索引。
(firstrow.to_i-1..lastrow.to_i-1).each_with_index do |row, i|
@licnum1 = data.at(row).dln
@licnum2 = data.at(row+1).dln
@nino = data.at(row).nino
@postcode = data.at(row).pcode
@endor_cd = data.at(row).endor_cd
@ct_cd = data.at(row).ct_cd
#Login only required once for each new user-account
if
loginrequired == true
logon_to_vdr #def for this is in hooks
click_on 'P and D'
loginrequired = false
end
#This is the check against the database and is required for every line in the .csv file
check_ctcd #def for this is in hooks
rescue => e
# log the error and index here
...
并且您可以制作自己的自定义错误,并仅拯救某种类型,以便您不会悄悄地挽救其他错误。