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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With