Commit a59c51b7 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'dz-error-tracking-handle-invalid-payload' into 'master'

Improve error tracking error handling

See merge request gitlab-org/gitlab!73557
parents d902854a 78e67fc8
{ {
"description": "Error tracking event payload", "description": "Error tracking event payload",
"type": "object", "type": "object",
"required": [], "required": ["exception"],
"properties": { "properties": {
"environment": { "environment": {
"type": "string" "type": "string"
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
}, },
"exception": { "exception": {
"type": "object", "type": "object",
"required": [], "required": ["values"],
"properties": { "properties": {
"values": { "values": {
"type": "array", "type": "array",
......
...@@ -12,6 +12,10 @@ module API ...@@ -12,6 +12,10 @@ module API
content_type :txt, 'text/plain' content_type :txt, 'text/plain'
default_format :envelope default_format :envelope
rescue_from ActiveRecord::RecordInvalid do |e|
render_api_error!(e.message, 400)
end
before do before do
not_found!('Project') unless project not_found!('Project') unless project
not_found! unless feature_enabled? not_found! unless feature_enabled?
...@@ -50,6 +54,12 @@ module API ...@@ -50,6 +54,12 @@ module API
bad_request!('Failed to parse sentry request') bad_request!('Failed to parse sentry request')
end end
end end
def validate_payload(payload)
unless ::ErrorTracking::Collector::PayloadValidator.new.valid?(payload)
bad_request!('Unsupported sentry payload')
end
end
end end
desc 'Submit error tracking event to the project as envelope' do desc 'Submit error tracking event to the project as envelope' do
...@@ -88,6 +98,8 @@ module API ...@@ -88,6 +98,8 @@ module API
# We don't have use for transaction request yet, # We don't have use for transaction request yet,
# so we record only event one. # so we record only event one.
if type == 'event' if type == 'event'
validate_payload(parsed_request[:event])
::ErrorTracking::CollectErrorService ::ErrorTracking::CollectErrorService
.new(project, nil, event: parsed_request[:event]) .new(project, nil, event: parsed_request[:event])
.execute .execute
...@@ -125,6 +137,8 @@ module API ...@@ -125,6 +137,8 @@ module API
bad_request!('Failed to parse sentry request') bad_request!('Failed to parse sentry request')
end end
validate_payload(parsed_body)
::ErrorTracking::CollectErrorService ::ErrorTracking::CollectErrorService
.new(project, nil, event: parsed_body) .new(project, nil, event: parsed_body)
.execute .execute
......
# frozen_string_literal: true
module ErrorTracking
module Collector
class PayloadValidator
PAYLOAD_SCHEMA_PATH = Rails.root.join('app', 'validators', 'json_schemas', 'error_tracking_event_payload.json').to_s
def valid?(payload)
JSONSchemer.schema(Pathname.new(PAYLOAD_SCHEMA_PATH)).valid?(payload)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ErrorTracking::Collector::PayloadValidator do
describe '#valid?' do
RSpec.shared_examples 'valid payload' do
it 'returns true' do
expect(described_class.new.valid?(payload)).to be_truthy
end
end
RSpec.shared_examples 'invalid payload' do
it 'returns false' do
expect(described_class.new.valid?(payload)).to be_falsey
end
end
context 'ruby payload' do
let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/parsed_event.json')) }
it_behaves_like 'valid payload'
end
context 'python payload' do
let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/python_event.json')) }
it_behaves_like 'valid payload'
end
context 'browser payload' do
let(:payload) { Gitlab::Json.parse(fixture_file('error_tracking/browser_event.json')) }
it_behaves_like 'valid payload'
end
context 'empty payload' do
let(:payload) { '' }
it_behaves_like 'invalid payload'
end
context 'invalid payload' do
let(:payload) { { 'foo' => 'bar' } }
it_behaves_like 'invalid payload'
end
end
end
...@@ -136,6 +136,21 @@ RSpec.describe API::ErrorTracking::Collector do ...@@ -136,6 +136,21 @@ RSpec.describe API::ErrorTracking::Collector do
it_behaves_like 'bad request' it_behaves_like 'bad request'
end end
context 'body with string instead of json' do
let(:params) { '"********"' }
it_behaves_like 'bad request'
end
context 'collector fails with validation error' do
before do
allow(::ErrorTracking::CollectErrorService)
.to receive(:new).and_raise(ActiveRecord::RecordInvalid)
end
it_behaves_like 'bad request'
end
context 'gzip body' do context 'gzip body' do
let(:headers) do let(:headers) do
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment