2016-02-10 75 views
0

我有一個與谷歌日曆API集成的Rails應用程序。應用程序部署在heroku上。以下代碼在localhost中工作,但在生產中遇到了nomethoderror,如下所示。這是爲什麼發生?導軌nomethoderror只在生產

錯誤的get_own_events:

Attempting refresh of access token & retry of request 
2016-02-10T13:24:34.161850+00:00 app[web.1]: 
2016-02-10T13:24:34.161853+00:00 app[web.1]: NoMethodError (undefined method `each' for nil:NilClass): 
2016-02-10T13:24:34.161854+00:00 app[web.1]: lib/google_calendar_api.rb:91:in `get_own_events' 
2016-02-10T13:24:34.161855+00:00 app[web.1]: app/controllers/events_controller.rb:18:in `index' 

錯誤的忙碌事件:

2016-02-10T13:24:00.716112+00:00 app[web.1]: Attempting refresh of access token & retry of request 
2016-02-10T13:24:00.779120+00:00 app[web.1]: NoMethodError (undefined method `[]' for nil:NilClass): 
2016-02-10T13:24:00.779121+00:00 app[web.1]: lib/google_calendar_api.rb:38:in `get_busy_events' 
2016-02-10T13:24:00.779121+00:00 app[web.1]: app/controllers/events_controller.rb:20:in `index' 
events_controller

if params['start'] && params['end'] 
    @start_time = params['start'].to_datetime.rfc3339 
    @end_time = params['end'].to_datetime.rfc3339 
    @timezone = params['timezoneParam'] 
    if @user == @current_user 
     @results = get_own_events(@google, @start_time, @end_time, @timezone) 
    else 
     @results = get_busy_events(@google, @start_time, @end_time, @timezone) 
    end 
    end 

get_own_events方法:

def get_own_events(social_object, start_time, end_time, timezone) 
    client = init_google_api_calendar_client(social_object) 
    old_token = client.authorization.access_token 
    service = client.discovered_api('calendar', 'v3') 

    #API request/response 
    result_raw = client.execute(
    :api_method => service.events.list, 
    :parameters => { 'calendarId' => social_object.email, 
        'timeMin' => start_time, 
        'timeMax' => end_time, 
        'timeZone' => timezone }, 
    :headers => {'Content-Type' => 'application/json'}) 

    #token refresh if needed 
    new_token = client.authorization.access_token 
    if old_token != new_token 
    social_object.update_attribute(:token, new_token) 
    get_own_events(social_object, start_time, end_time, timezone) 
    end 

    #API response parsing 
    result = JSON.parse(result_raw.body)['items'] 
    #result_timezone = JSON.parse(result_raw.body)['timeZone'] 

    #changing response to fullcalendar format 
    formatted_event_array = [] 

    result.each do |event| #THIS IS LINE 91 
    start_time = event['start']['dateTime'].to_datetime.rfc822 
    end_time = event['end']['dateTime'].to_datetime.rfc822 
    #timezone = result_timezone 
    all_day = false 
    title = event['summary'] 
    formatted_event = {} 
    formatted_event['title'] = title 
    formatted_event['start'] = start_time 
    formatted_event['end'] = end_time 
    formatted_event['allDay'] = all_day 
    formatted_event_array << formatted_event 
    end 

    return formatted_event_array 
end 

get_busy_events方法:

def get_busy_events(social_object, start_time, end_time, timezone) 
    client = init_google_api_calendar_client(social_object) 
    old_token = client.authorization.access_token 
    service = client.discovered_api('calendar', 'v3') 

    #API request/response 
    result_raw = client.execute(
    :api_method => service.freebusy.query, 
    :body => JSON.dump({ 
      :timeMin => start_time, 
      :timeMax => end_time, 
      :timeZone => timezone, 
      :items => [{ :id => social_object.email }]}), 
    :headers => {'Content-Type' => 'application/json'}) 

    #token refresh if needed 
    new_token = client.authorization.access_token 
    if old_token != new_token 
    social_object.update_attribute(:token, new_token) 
    get_busy_events(social_object,start_time, end_time, timezone) 
    end 

    #API response parsing 
    result = JSON.parse(result_raw.body)['calendars'][social_object.email]['busy'] #THIS IS LINE 38 

    #changing response to fullcalendar format 
    formatted_event_array = [] 

    result.each do |event| 
    start_time = event['start'].to_datetime.rfc822 
    end_time = event['end'].to_datetime.rfc822 
    formatted_event = {} 
    formatted_event['title'] = 'busy' 
    formatted_event['start'] = start_time 
    formatted_event['end'] = end_time 
    #no allDay in freebusy response, so time difference must be checked 
    if event['start'].to_datetime + 1.day <= event['end'].to_datetime 
     formatted_event['allDay'] = true 
    else 
     formatted_event['allDay'] = false 
    end 
    formatted_event_array << formatted_event 
    end 

    return formatted_event_array 
end 
+0

哪些線是38和91'的lib/google_calendar_api.rb' –

回答

2

有效正是這種

result = JSON.parse(result_raw.body)['calendars'][social_object.email]['busy'] 

如果JSON.parse(result_raw.body)['calendars'][social_object.email]['busy']是零那麼這個

result.each do |event| 
# code 
end 

試圖遍歷爲零。

你可以修復與保護條款

return formatted_event_array if result.nil? 
result.each do |event| 
# code 
end 

但對我來說這是有點掩蓋了裂縫。另一個錯誤是因爲同一條線。

假設 parsed_body = JSON.parse(result_raw.body)

通過鏈接哈希調用,無需檢查,如果 parsed_body['calendars']是零,它會毀掉自己的錯誤,或者 parsed_body['calendars'][social_object.email]是零

那麼有效,你要檢查,如果這些都存在,並且parsed_body['calendars'][social_object.email]['busy']存在。如果他們不那麼想必返回空數組

所以

if parsed_body['calendars'] && parsed_body['calendars'][social_object.email] && parsed_body['calendars'][social_object.email]['busy'] 
+0

J-dexx,與方法,我應該檢查它是否存在? –

+0

你可以使用'.present?',但你應該可以使用標準的,如果 –

+0

j-dexx,你能更新你的答案嗎?我已經遇到過幾次了,我想確保從現在起每次都會正確使用它。所以,如果你能給我看一些示例代碼,並列出一些應該使用這種方法的情況,那將是超級棒的。 –