使用救援并确保代码中间(Using rescue and ensure in the middle of code)

编程入门 行业动态 更新时间:2024-10-26 12:30:15
使用救援并确保代码中间(Using rescue and ensure in the middle of code)

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

Still new to Ruby - I've had a look at some of the answers to seemingly similar questions but, to be honest, I couldn't get my head around them.

I have some code that reads a .csv file. The data is split into groups of 40-50 rows per user record and validates data in the rows against a database accessed via a website.

A login is required for each record, but once that user has logged in each row in the .csv file can be checked until the next user is reached, at which point the user logs out.

All that's working, however, if an error occurs (e.g. a different result on the website than the expected result on the .csv file) the program stops.

I need something that will a) at tell me which line on the file the error occurred b) log the row to be output when it's finished running, and iii) restart the program from the next line in the .csv file

The code I have so far is below

Thanks in advance,

Peter

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

最满意答案

您似乎需要一些错误记录,因为您显然不知道您接收的错误类型或位置。 如果此脚本是独立的,您可以将$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是全局的,由$ variable前缀表示。)如果是这种情况,你可能想要实现一个begin; rescue; end begin; rescue; end begin; rescue; end结构并创建自己的日志文件,这样就不会影响$stderr 。

再一次,既然你不知道错误发生在哪里,你想用begin; end包装整个脚本begin; end 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 在此块内部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

我希望这有帮助!

It seems like you need some error logging since you apparently don't know what type of error you're receiving or where. If this script is standalone you can redirect $stderr to file so that you can read what went wrong.

# put this line at the top of your script $stderr = File.open("/path/to/your/logfile.log","a")

When an error occurs, ruby will automatically write the error message, class, and backtrace to the log file you specify so that you can trace back the line where things are not going as expected. (When you run a script from the command line, normally this information will just get blurted back to the terminal when an error happens.)

For example, on my desktop I created a file log_stderr.rb with the following (line numbers included):

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"

Also on my desktop I created the file raise_error.rb with the following (to deepen the backtrace for better example output):

1 # call raise to generate an error arbitrarily 2 # to halt execution and exit the program. 3 raise RuntimeError, 'the program stopped working!'

When I run ruby log_stderr.rb from the command line, my_log.log is created on my desktop with the following:

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>'

If you are working in a larger environment where your script is being called amidst other scripts then you probably do not want to redirect $stderr because this would affect everything else running in the environment. ($stderr is global as indicated by the $ variable prefix.) If this is the case you would want to implement a begin; rescue; end structure and also make your own logfile so that you don't affect $stderr.

Again, since you don't know where the error is happening you want to wrap the whole script with 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

If you find that your error is happening only in the block (firstrow.to_i-1..lastrow.to_i-1).each do |row| you can place the begin; end inside of this block to have access to the local row variable, or else create a top level variable independent of the block and assign it during each iteration of the block to report to your logfile:

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

I hope this helps!

更多推荐

本文发布于:2023-08-01 18:47:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1362831.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   rescue   ensure   middle   code

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!