feat(graphql): add error codes to graphql errors

This commit is contained in:
Paul Chavard 2023-04-18 09:48:38 +02:00
parent 2a09f1d505
commit fbae6d941d
5 changed files with 37 additions and 11 deletions

View file

@ -5,7 +5,9 @@ class API::V2::GraphqlController < API::V2::BaseController
render json: result render json: result
rescue GraphQL::ParseError, JSON::ParserError => exception rescue GraphQL::ParseError, JSON::ParserError => exception
handle_parse_error(exception) handle_parse_error(exception, :graphql_parse_failed)
rescue ArgumentError => exception
handle_parse_error(exception, :bad_request)
rescue => exception rescue => exception
if Rails.env.production? if Rails.env.production?
handle_error_in_production(exception) handle_error_in_production(exception)
@ -33,7 +35,12 @@ class API::V2::GraphqlController < API::V2::BaseController
rescue ActionDispatch::Http::Parameters::ParseError => exception rescue ActionDispatch::Http::Parameters::ParseError => exception
render json: { render json: {
errors: [ errors: [
{ message: exception.cause.message } {
message: exception.cause.message,
extensions: {
code: :bad_request
}
}
], ],
data: nil data: nil
}, status: 400 }, status: 400
@ -75,10 +82,13 @@ class API::V2::GraphqlController < API::V2::BaseController
end end
end end
def handle_parse_error(exception) def handle_parse_error(exception, code)
render json: { render json: {
errors: [ errors: [
{ message: exception.message } {
message: exception.message,
extensions: { code: }
}
], ],
data: nil data: nil
}, status: 400 }, status: 400
@ -90,22 +100,32 @@ class API::V2::GraphqlController < API::V2::BaseController
render json: { render json: {
errors: [ errors: [
{ message: exception.message, backtrace: exception.backtrace } {
message: exception.message,
extensions: {
code: :internal_server_error,
backtrace: exception.backtrace
}
}
], ],
data: nil data: nil
}, status: 500 }, status: 500
end end
def handle_error_in_production(exception) def handle_error_in_production(exception)
extra = { exception_id: SecureRandom.uuid } exception_id = SecureRandom.uuid
Sentry.capture_exception(exception, extra:) Sentry.with_scope do |scope|
scope.set_tags(exception_id:)
Sentry.capture_exception(exception)
end
render json: { render json: {
errors: [ errors: [
{ {
message: "Internal Server Error", message: "Internal Server Error",
extensions: { extensions: {
exception: { id: extra[:exception_id] } code: :internal_server_error,
exception_id:
} }
} }
], ],

View file

@ -50,7 +50,7 @@ class API::V2::Schema < GraphQL::Schema
when GroupeInstructeur when GroupeInstructeur
Types::GroupeInstructeurType Types::GroupeInstructeurType
else else
raise GraphQL::ExecutionError.new("Unexpected object: #{object}") type_definition
end end
end end

View file

@ -8,7 +8,7 @@ class API::V2::StoredQuery
when 'introspection' when 'introspection'
GraphQL::Introspection::INTROSPECTION_QUERY GraphQL::Introspection::INTROSPECTION_QUERY
else else
raise GraphQL::ExecutionError.new("No query with id \"#{query_id}\"") raise GraphQL::ExecutionError.new("No query with id \"#{query_id}\"", extensions: { code: :bad_request })
end end
end end

View file

@ -1,5 +1,11 @@
module Types module Types
class BaseObject < GraphQL::Schema::Object class BaseObject < GraphQL::Schema::Object
field_class BaseField field_class BaseField
class InvalidNullError < GraphQL::InvalidNullError
def to_h
super.merge(extensions: { code: :invalid_null })
end
end
end end
end end

View file

@ -684,7 +684,7 @@ describe API::V2::GraphqlController do
end end
it "should return an error" do it "should return an error" do
expect(gql_errors).to eq([{ message: "Cannot return null for non-nullable field PersonneMorale.siegeSocial" }]) expect(gql_errors).to eq([{ message: "Cannot return null for non-nullable field PersonneMorale.siegeSocial", extensions: { code: "invalid_null" } }])
end end
end end
end end