5

I'm running into an issue where I send an insert_calendar request to Google Calendar API V3, and I get back the following response:

Sending HTTP post https://www.googleapis.com/calendar/v3/calendars?

503

#<HTTP::Message:0x000000124eb008 
  @http_header=#<HTTP::Message::Headers:0x000000124eafe0 
  @http_version="1.1", 
  @body_size=0, 
  @chunked=false,
  @request_method="POST", 
  @request_uri=#<Addressable::URI:0x9275f20 URI:https://www.googleapis.com/calendar/v3/calendars?>, 
  @request_query=nil, 
  @request_absolute_uri=nil, 
  @status_code=503, 
  @reason_phrase="Service Unavailable", 
  @body_type=nil, 
  @body_charset=nil, 
  @body_date=nil, 
  @body_encoding=#<Encoding:UTF-8>, 
  @is_request=false, 
  @header_item=[
    ["Vary", "Origin"], 
    ["Vary", "X-Origin"], 
    ["Content-Type", "application/json; charset=UTF-8"], 
    ["Content-Encoding", "gzip"], 
    ["Date", "Fri, 25 Aug 2017 20:16:34 GMT"], 
    ["Expires", "Fri, 25 Aug 2017 20:16:34 GMT"], 
    ["Cache-Control", "private, max-age=0"], 
    ["X-Content-Type-Options", "nosniff"], 
    ["X-Frame-Options", "SAMEORIGIN"], 
    ["X-XSS-Protection", "1; mode=block"], 
    ["Server", "GSE"], ["Alt-Svc", "quic=\":443\"; ma=2592000; v=\"39,38,37,35\""], 
    ["Transfer-Encoding", "chunked"]
  ], 
  @dumped=false>, 
  @peer_cert=#<OpenSSL::X509::Certificate: 
    subject=#<OpenSSL::X509::Name:0x00000012600998>, 
    issuer=#<OpenSSL::X509::Name:0x000000126009c0>, 
    serial=#<OpenSSL::BN:0x000000126009e8>, 
    not_before=2017-08-15 16:06:52 UTC, 
    not_after=2017-11-07 16:04:00 UTC
  >, 
  @http_body=#<HTTP::Message::Body:0x000000124eaf68 
    @body="{\n \"error\": {\n \"errors\": [\n{\n \"domain\": \"global\",\n \"reason\": \"backendError\",\n \"message\": \"Backend Error\"\n }\n ],\n \"code\": 503,\n \"message\": \"Backend Error\"\n }\n}\n",
    @size=0, 
    @positions=nil, 
    @chunk_size=nil
  >, 
  @previous=nil>

Caught error Server error

Error - #<Google::Apis::ServerError: Server error>

I'm using the Google API Ruby Client, details here:

google-api-client (0.13.1)
  addressable (~> 2.5, >= 2.5.1)
  googleauth (~> 0.5)
  httpclient (>= 2.8.1, < 3.0)
  mime-types (~> 3.0)
  representable (~> 3.0)
  retriable (>= 2.0, < 4.0)

The issue I'm having is not encountering the error, but that the calendar is successfully inserted.

As you can see from the response I get nothing back that tells me it was successful in spite of the 503, such as a Google Calendar ID.

The impact this has on my application is that I do not know I have successfully synced, and in fact, by following the docs, I implement and exponential backoff, and so I continue to create duplicate calendars on my users' Google Calendars.

In the end, I have a bunch of orphan calendars showing up that I must remove with a string match.

Is this expected? Is there anything I can do to mitigate this?

This happens with regularity, and is not an isolated case.


The code in question:

def handle_calendar_response(response, error)
  self.update_column('last_synced_at', Time.now.utc)
  if error.present?
    Airbrake.notify('Sync Calendar Sync Error', {
      error: error,
      message: error.message,
      calendar: self
    })

    # String match :(
    if error.message =~ /not.?found/i || error.message =~ /forbidden/i
      Airbrake.notify('Removing user deleted calendar', {
        calendar: self,
        google_calendar_id: self.google_calendar_id,
        error: error,
        message: error.message
      })
      self.publish_to_google = false
      self.google_calendar_id = nil
      self.save!
    end
  end
end

...

def insert_calendar
  @client.insert_calendar(google_calendar_object) do |response, error|
    handle_calendar_response(response, error)
    if response.present?
      self.google_calendar_id = response.id
      self.save!
    end
  end
end

These are methods from a representation of a synced calendar in our data model. You can call insert_calendar to insert it. We always take the same action on a response from Google, if we are inserting, updating, or deleting, we always call handle_calendar_response.

zkwentz
  • 1,095
  • 5
  • 22
  • 44
  • 3
    Can you please send code what use are using? – Samuel Tulach Aug 28 '17 at 15:42
  • Will do. Apologies. – zkwentz Aug 28 '17 at 17:56
  • 1
    I don't think it is expected. You can file a bug report with Google at https://developers.google.com/google-apps/calendar/support . Seeing the "Backend error" and "server error" messages returned from Google Calendar API, it looks like it's something on their end. Perhaps you can mitigate by parsing the response if it is 503 with "backend error" in the response body, you proceed in your code as if it was successful. – slasky Aug 29 '17 at 17:52
  • Where can we see your script? – Tanaike Aug 30 '17 at 02:32
  • I have faced this exact same issue before! can you share the body you are sending in the request? – Bamieh Sep 03 '17 at 22:15
  • @Tanaike Code added. – zkwentz Sep 05 '17 at 21:53

1 Answers1

1

Since the errors is in the google backend system there is not really much you can do about fixing it on their side aside of filing a bug report. However you can handle this on your side with adding your own identifier and putting it in the private extended properties of the calendar you want to create. The identifier can be something like combination of the date/time and subject of the event or even a random UIID just as long as you guarantee it is unique. Then before issuing another request when you get the error first go through the users calendars and check if there is an event with the identifier on the same date. This assumes that you have read rights for the users calendars. Hope this helps.

vl4d1m1r4
  • 1,688
  • 12
  • 21