Skip to content

Commit

Permalink
Raise insertion errors from BigQuery
Browse files Browse the repository at this point in the history
When inserting data in to BigQuery we need to inspect the response for
errors as although it may have a 200 HTTP status code, schema-related
errors that occur on insertion are included in the error information of
the response.

See
https://cloud.google.com/bigquery/docs/error-messages#streaming-success
for more information on this.
  • Loading branch information
thomasleese committed Jul 14, 2022
1 parent 7c4993a commit 7ccea52
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
18 changes: 17 additions & 1 deletion lib/dfe/analytics/send_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,25 @@ def perform(events)
if DfE::Analytics.log_only?
Rails.logger.info("DfE::Analytics: #{events.inspect}")
else
DfE::Analytics.events_client.insert(events, ignore_unknown: true)
response = DfE::Analytics.events_client.insert(events, ignore_unknown: true)
raise SendEventsError, response.insert_errors unless response.success?
end
end
end

class SendEventsError < StandardError
attr_reader :insert_errors

def initialize(insert_errors)
@insert_errors = insert_errors

message = insert_errors
.flat_map(&:errors)
.map { |error| error['message'] }
.compact.join("\n")

super("Could not insert all events:\n#{message}")
end
end
end
end
4 changes: 3 additions & 1 deletion lib/dfe/analytics/testing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ def switch_test_mode(test_mode)
end

class StubClient
Response = Struct.new(:success?)

def insert(*)
true
Response.new(true)
end
end

Expand Down
21 changes: 21 additions & 0 deletions lib/dfe/analytics/testing/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ def stub_analytics_event_submission
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
end

def stub_analytics_event_submission_with_insert_errors
stub_bigquery_auth!

body = {
insertErrors: [
{
index: 0,
errors: [
{
reason: 'error',
message: 'An error.'
}
]
}
]
}

stub_request(:post, /bigquery.googleapis.com/)
.to_return(status: 200, body: body.to_json, headers: { 'Content-Type' => 'application/json' })
end

def with_analytics_config(options)
old_config = DfE::Analytics.config.dup
DfE::Analytics.configure do |config|
Expand Down
20 changes: 20 additions & 0 deletions spec/dfe/analytics/send_events_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@
end
end

context 'when the request is not successful' do
before { stub_analytics_event_submission_with_insert_errors }

subject(:perform) do
DfE::Analytics::Testing.webmock! do
described_class.new.perform([event.as_json])
end
end

it 'raises an exception' do
expect { perform }.to raise_error(DfE::Analytics::SendEventsError, /An error./)
end

it 'contains the insert errors' do
perform
rescue DfE::Analytics::SendEventsError => e
expect(e.insert_errors).to_not be_empty
end
end

context 'when "log_only" is set' do
before do
allow(DfE::Analytics).to receive(:log_only?).and_return true
Expand Down

0 comments on commit 7ccea52

Please sign in to comment.