Ошибки задачи Rake с: JSON :: ParserError: 765: неожиданный токен в '', но отлично работает в консоли rails - PullRequest
1 голос
/ 15 июня 2019

У меня есть задание по рейку, которое перебирает страницы базы данных карточных игр и проверяет карты в каждой колоде.До недавнего времени это работало нормально (проверено 34000 страниц по 25 колод в каждой, нет проблем), но недавно это перестало работать, когда я запускаю задачу rake, и я получаю сообщение об ошибке:

JSON :: ParserError: 765: неожиданнотокен в ''

Чтобы отладить это, я попытался запустить каждую строку запроса get и json parse вручную в консоли rails, и каждый раз он работает нормально.Что еще страннее, я установил pry, и он работает каждый раз, когда я вручную выполняю анализ json с pry (хотя и занимает много времени).

Вот задача с граблями:

desc "Create Cards"
require 'net/http'
require 'json'
task :create_cards => :environment do
  # Get the total number of pages of decks
  uri = URI("https://www.keyforgegame.com/api/decks/")
  response = Net::HTTP.get(URI(uri))
  json = JSON.parse(response)
  deck_count = json["count"]

  # Set variables
  page_number = 1
  page_size = 25 # 25 is the max page size
  page_limit = deck_count / 25
  card_list = Card.where(is_maverick: false)

  # Updates Card List (non-mavericks) - there are 740 cards so we stop when we have that many
  # example uri: https://www.keyforgegame.com/api/decks/?page=1&page_size=30&search=&links=cards
  puts "Updating Card List..."
  until page_number > page_limit || Card.where(is_maverick: false).length == 740
    uri = URI("https://www.keyforgegame.com/api/decks/?page=#{page_number}&page_size=#{page_size}&search=&links=cards")
    response = Net::HTTP.get(URI(uri))


    json = JSON.parse(response) # task errors here!


    cards = json["_linked"]["cards"]
    cards.each do |card|
      unless Card.exists?(:card_id => card["id"])
        Card.create({
        card_id: card["id"],
        amber: card["amber"],
        card_number: card["card_number"],
        card_text: card["card_text"],
        card_title: card["card_title"],
        card_type: card["card_type"],
        expansion: card["expansion"],
        flavor_text: card["flavor_text"],
        front_image: card["front_image"],
        house: card["house"],
        is_maverick: card["is_maverick"],
        power: card["power"],
        rarity: card["rarity"],
        traits: card["traits"],
        })
      end
    end

    puts "#{page_number}/#{page_limit} - Cards: #{Card.where(is_maverick: false).length}"
    page_number = (page_number + 1)
  end
end

Первый jsonparse, где он получает общее количество страниц колод, работает нормально.Это сбой json в блоке till, который завершается неудачно (я пометил строку комментарием на этот счет).

Как я уже сказал, если я попробую это в консоли, все будет работать нормально, и я смогу разобратьJSON без ошибок, буквально копируя и вставляя строки из файла в консоль rails.

1 Ответ

0 голосов
/ 15 июня 2019

Поскольку вы зацикливаетесь на API, возможно, существуют ограничения скорости. Публичные API обычно имеют ограничения в секунду. Вы можете попробовать добавить режим сна, чтобы замедлить ваши запросы, не зная, сколько вы зарабатываете в секунду. Я проверил с помощью простого цикла и похоже, что ответ возвращает пустую строку, если вы слишком быстро нажали API.

url='https://www.keyforgegame.com/api/decks/?page=1&page_size=30&search=&links=cards'
uri = URI(url)
i = 1
1000.times do
  puts i.to_s
  i += 1
  response =  Net::HTTP.get(URI(uri))
  begin
    j = JSON.parse(response)
  rescue
    puts response
    #= ""
  end
end

Я играл с этим до тех пор, пока цикл не перестал возвращать пустую строку после 3-го запроса и не заставил ее работать с sleep 5 внутри каждого цикла, так что вы, вероятно, можете добавить в качестве первой строки внутри цикла. Но вам, вероятно, следует добавить обработку ошибок в задачу rake на случай, если возникнут какие-либо другие ошибки API.

Так что сейчас вы, вероятно, можете просто сделать это

until page_number > page_limit || Card.where(is_maverick: false).length == 740
  sleep 5
  # rest of your loop code, maybe add a rescue like I've shown
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...