From f8071537247498fee114af5f2f0135493e4faf9c Mon Sep 17 00:00:00 2001 From: Jan Vitturi Date: Wed, 24 Jun 2020 11:25:39 +0200 Subject: [PATCH 1/3] Handle JSON parse errors --- lib/request_handler/body_parser.rb | 2 ++ lib/request_handler/error.rb | 2 ++ spec/request_handler/body_parser_spec.rb | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/lib/request_handler/body_parser.rb b/lib/request_handler/body_parser.rb index 827fa7e..aec0942 100644 --- a/lib/request_handler/body_parser.rb +++ b/lib/request_handler/body_parser.rb @@ -30,6 +30,8 @@ def request_body b.rewind b = b.read b.empty? ? {} : MultiJson.load(b) + rescue MultiJson::ParseError => e + raise ParseError, json: e.message end attr_reader :request, :schema, :schema_options, :type diff --git a/lib/request_handler/error.rb b/lib/request_handler/error.rb index d1720ee..647409b 100644 --- a/lib/request_handler/error.rb +++ b/lib/request_handler/error.rb @@ -29,6 +29,8 @@ def errors RequestHandler.configuration.raise_jsonapi_errors ? @errors : [] end end + class ParseError < ExternalBaseError + end class MissingArgumentError < InternalBaseError end class ExternalArgumentError < JsonApiError diff --git a/spec/request_handler/body_parser_spec.rb b/spec/request_handler/body_parser_spec.rb index b9f8172..5cc9b01 100644 --- a/spec/request_handler/body_parser_spec.rb +++ b/spec/request_handler/body_parser_spec.rb @@ -103,6 +103,20 @@ .to raise_error(RequestHandler::MissingArgumentError) end + it 'fails if the request body is not json' do + schema = Dry::Schema.JSON {} + expect do + described_class.new( + schema: schema, + type: type, + request: instance_double('Rack::Request', + params: {}, + body: StringIO.new('foo')) + ).run + end + .to raise_error(RequestHandler::ParseError) + end + it "doesn't fail if the request body does not contain a data hash" do schema = Dry::Schema.JSON {} expect do From 06de6900f0b6301df0bb4d928bd90ea04b5dc603 Mon Sep 17 00:00:00 2001 From: Jan Vitturi Date: Thu, 25 Jun 2020 08:49:42 +0200 Subject: [PATCH 2/3] Add parse error changes to changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c8327a..1dd05ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- `ParseError` error type + +### Changed +- Rescue and translate `MultiJson::ParseError` while parsing body + ## [2.1.0] - 2020-04-01 ### Added - Headers validation From ab80ff4534ef692ca8b5c90025b019d8e4aad5be Mon Sep 17 00:00:00 2001 From: Jan Vitturi Date: Thu, 2 Jul 2020 08:56:36 +0200 Subject: [PATCH 3/3] Make JSON parse error a JSON:API error --- CHANGELOG.md | 2 +- README.md | 1 + lib/request_handler/body_parser.rb | 4 +++- lib/request_handler/error.rb | 4 ++-- spec/request_handler/body_parser_spec.rb | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dd05ea..b4550ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added -- `ParseError` error type +- `INVALID_BODY_FORMAT` JSON:API error ### Changed - Rescue and translate `MultiJson::ParseError` while parsing body diff --git a/README.md b/README.md index ed90393..f996019 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,7 @@ with one issue per line. | `:code` | `:status` | What is it? | |:--------------------------|:----------|:------------| | INVALID_RESOURCE_SCHEMA | 422 | Resource did not pass configured validation | +| INVALID_BODY_FORMAT | 400 | Request body is invalid JSON | | INVALID_QUERY_PARAMETER | 400 | Query parameter violates syntax or did not pass configured validation | | MISSING_QUERY_PARAMETER | 400 | Query parameter required in configuration is missing | | INVALID_JSON_API | 400 | Request body violates JSON:API syntax | diff --git a/lib/request_handler/body_parser.rb b/lib/request_handler/body_parser.rb index aec0942..c8f9512 100644 --- a/lib/request_handler/body_parser.rb +++ b/lib/request_handler/body_parser.rb @@ -31,7 +31,9 @@ def request_body b = b.read b.empty? ? {} : MultiJson.load(b) rescue MultiJson::ParseError => e - raise ParseError, json: e.message + raise BodyFormatError, [{ status: '400', + code: 'INVALID_BODY_FORMAT', + detail: e.message }] end attr_reader :request, :schema, :schema_options, :type diff --git a/lib/request_handler/error.rb b/lib/request_handler/error.rb index 647409b..85b02a6 100644 --- a/lib/request_handler/error.rb +++ b/lib/request_handler/error.rb @@ -29,8 +29,6 @@ def errors RequestHandler.configuration.raise_jsonapi_errors ? @errors : [] end end - class ParseError < ExternalBaseError - end class MissingArgumentError < InternalBaseError end class ExternalArgumentError < JsonApiError @@ -44,6 +42,8 @@ class OptionNotAllowedError < JsonApiError class NoConfigAvailableError < InternalBaseError end + class BodyFormatError < ExternalArgumentError + end class BodyParamsError < ExternalArgumentError end class FieldsetsParamsError < ExternalArgumentError diff --git a/spec/request_handler/body_parser_spec.rb b/spec/request_handler/body_parser_spec.rb index 5cc9b01..a057d85 100644 --- a/spec/request_handler/body_parser_spec.rb +++ b/spec/request_handler/body_parser_spec.rb @@ -114,7 +114,7 @@ body: StringIO.new('foo')) ).run end - .to raise_error(RequestHandler::ParseError) + .to raise_error(RequestHandler::BodyFormatError) end it "doesn't fail if the request body does not contain a data hash" do