2016-03-09 5 views
0

Еще новичок в Ruby - я посмотрел на некоторые ответы на похожие вопросы, но, честно говоря, я не мог окунуться в них.Использование спасения и обеспечение в середине кода

У меня есть код, который читает CSV-файл. Данные разбиваются на группы по 40-50 строк на запись пользователя и проверяют данные в строках по базе данных, доступной через веб-сайт.

Для каждой записи требуется логин, но после того, как пользователь зарегистрировался в каждой строке в CSV-файле, можно проверить, пока не будет достигнут следующий пользователь, после чего пользователь выйдет из системы.

Все, что работает, однако, если произошла ошибка (например, на веб-сайте, отличном от ожидаемого результата в файле .csv), программа останавливается.

мне нужно что-то, что будет а) по мне сказать, какая строка в файле произошла ошибка б) войти в ряд, который будет выводиться, когда он закончит работу, и 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

Удалось ли вам получить обратную трассировку или сообщение об ошибке? 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 из команды line, 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. В частности, раздел rescue => e. Не могли бы вы объяснить, что более подробно, что означает => e, и как мы будем регистрировать ошибку и индекс ниже, пожалуйста? Спасибо – Tom

+0

Между нами трое и комбинацией идей из ответов выше, отсортировано! Благодарю. – Peter

+0

'e' - это то, что возвращает' rescue', и это объект ruby. если вы делаете 'puts e', он покажет вам, что такое ошибка @Tom –