2016-03-09 23 views
0

Ruby還是個新手 - 我看了一些看似類似問題的答案,但說實話,我無法擺脫困境。使用救援並確保在代碼中間

我有一些讀取.csv文件的代碼。數據按每個用戶記錄分成40-50行組,並根據通過網站訪問的數據庫驗證行中的數據。

每個記錄都需要登錄,但是一旦該用戶登錄了.csv文件中的每一行,就可以檢查該用戶,直到到達下一個用戶,此時用戶註銷。

但是,如果發生錯誤(例如,網站上的結果不同於.csv文件上的預期結果),程序將停止運行。

我需要的東西,將 一)在告訴我發生了哪條線路上的文件錯誤 二)登錄該行輸出時,它的運行完畢後,和 三)重新啓動該程序從下一行的.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

您是否能夠獲得回溯或錯誤消息?當發生無法預料的異常時,Ruby會自動將這些內容打印到STDERR。如果您從命令行運行腳本,則通常會在終端窗口中顯示此輸出。也許這是作爲一個計劃任務運行,所以你不能看到任何信息,因爲一旦錯誤發生,屏幕就會消失? – DRSE

+0

我試圖類似,我發現我不能繞過RSpec的期望。它引發了這個異常,但沒有循環到下一個迭代 – Tom

回答

1

看起來好像你需要一些錯誤記錄,因爲你顯然不知道你正在接收什麼類型的錯誤或在哪裏。如果此腳本是獨立的,您可以將$stderr重定向到文件,以便您可以閱讀出錯的內容。

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

當錯誤發生時,紅寶石會自動寫入錯誤消息,類和回溯到您指定,這樣就可以追溯到裏的東西如預期不會行的日誌文件。 (當你從命令行運行一個腳本時,通常這個信息只會在發生錯誤時被脫機回終端。)

例如,在我的桌面上,我創建了一個文件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。日誌我的桌面上創建了以下內容:

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 

我希望這有助於!

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

而且你可以使自己的自定義錯誤,救援只有某一類型,這樣你就不會默默地拯救其他錯誤。

+0

我沒有得到這個。 Ruby也是新鮮事。特別是救援=> e部分。你能否詳細解釋一下,關於什麼=> e的意思,以及我們如何記錄下面的錯誤和索引?謝謝 – Tom

+0

在我們三人之間以及上述答案的組合中,排序!謝謝。 – Peter

+0

'e'是'rescue'返回的,它是一個紅寶石對象。如果你做'放入e',它會告訴你錯誤是什麼@Tom –