diff options
| author | Robert | 2017-08-21 20:24:50 +0200 |
|---|---|---|
| committer | Robert | 2017-08-22 09:37:30 +0200 |
| commit | 61c4a303183284fc107325aeeef5ace7a3e68c0c (patch) | |
| tree | 71bbfe5e5fe9eddb9e381aa0536b44476f461bc1 | |
| parent | 327b1ec771a056451b0635ba80cc346fa1765299 (diff) | |
| download | chouette-core-61c4a303183284fc107325aeeef5ace7a3e68c0c.tar.bz2 | |
Refs: #4273@3h;
Debugging Java Integration (ZipService -> HTTPService -> Object Creation)
- Created an ErrorFormat concern to see what went wrong in the HTTP call
as so many things can go wrong due to:
* Timeout Issues
* Illegal database setup or cleaning before tests
| -rw-r--r-- | app/controllers/api/v1/netex_imports_controller.rb | 5 | ||||
| -rw-r--r-- | app/controllers/support/error_format.rb | 15 | ||||
| -rw-r--r-- | app/models/concerns/error_format.rb | 25 | ||||
| -rw-r--r-- | app/services/http_service.rb | 15 | ||||
| -rw-r--r-- | app/services/retry_service.rb | 13 | ||||
| -rw-r--r-- | app/workers/workbench_import_worker.rb | 21 | ||||
| -rw-r--r-- | spec/models/concerns/error_format_spec.rb | 35 |
7 files changed, 107 insertions, 22 deletions
diff --git a/app/controllers/api/v1/netex_imports_controller.rb b/app/controllers/api/v1/netex_imports_controller.rb index ba7777654..7dc18a7be 100644 --- a/app/controllers/api/v1/netex_imports_controller.rb +++ b/app/controllers/api/v1/netex_imports_controller.rb @@ -44,7 +44,10 @@ module Api ReferentialMetadataKludge.make_metadata_from_name! netex_import_params['name'], referential_id: @new_referential.id # <<< REMOVE ME !!!! rescue ActiveRecord::RecordInvalid - render json: {errors: @new_referential.errors}, status: 406 + require 'pry' + binding.pry + # render json: {errors: @new_referential.errors}, status: 406 + render json: {errors: ErrorFormat.detailed(@new_referential)}, status: 406 finish_action! end diff --git a/app/controllers/support/error_format.rb b/app/controllers/support/error_format.rb new file mode 100644 index 000000000..567eece80 --- /dev/null +++ b/app/controllers/support/error_format.rb @@ -0,0 +1,15 @@ +module Support + module ErrorFormat extend self + + def detailed error_object + error_object.errors.each do + end + end + + + private + def detailed_messages errors + end + + end +end diff --git a/app/models/concerns/error_format.rb b/app/models/concerns/error_format.rb new file mode 100644 index 000000000..d7d15894c --- /dev/null +++ b/app/models/concerns/error_format.rb @@ -0,0 +1,25 @@ +module ErrorFormat extend self + + def details error_object + error_object.errors.messages.map(&partial(:detail, error_object)) + end + + + private + def detail error_object, error + { + error.first => { + error: error.last.first, + value: error_object[error.first] + } + } + end + + + def partial name, *partial_args + -> *lazy_args do + send(name, *(partial_args + lazy_args)) + end + end + +end diff --git a/app/services/http_service.rb b/app/services/http_service.rb index ae7d0e413..6cf8ef93b 100644 --- a/app/services/http_service.rb +++ b/app/services/http_service.rb @@ -20,7 +20,6 @@ module HTTPService extend self raise "Error on api request status : #{resp.status} => #{resp.body}" end end - # host: 'http://localhost:3000', # path: '/api/v1/netex_imports.json', # token: '13-74009c36638f587c9eafb1ce46e95585', @@ -32,14 +31,14 @@ module HTTPService extend self c.request :multipart c.request :url_encoded c.adapter Faraday.default_adapter - - if upload - name = upload.keys.first - value, mime_type, as_name = upload.values.first - params.update( name => Faraday::UploadIO.new(value, mime_type, as_name ) ) - end - + require 'pry' + binding.pry return c.post path, params end end + + # Expose this in order to make the service replaceable + def upload(*triple) + Faraday::UploadIO.new(*triple) + end end diff --git a/app/services/retry_service.rb b/app/services/retry_service.rb index 21b1def36..245dd32df 100644 --- a/app/services/retry_service.rb +++ b/app/services/retry_service.rb @@ -16,8 +16,9 @@ class RetryService # @param@ block: # This optional code is excuted before each retry, it is passed the result of the failed attempt, thus # an `Exception` and the number of execution already tried. - def initialize( delays: [], rescue_from: [], &blk ) + def initialize( delays: [], rescue_from: [], logger: nil, &blk ) @intervals = delays + @logger = logger @registered_exceptions = Array(rescue_from) << Retry @failure_callback = blk end @@ -31,6 +32,7 @@ class RetryService result = execute_protected blk return result if result.ok? @intervals.each_with_index do | interval, retry_count | + warn "retry #{retry_count + 1 }; sleeping #{interval}; cause: #{result.value.inspect}" sleep interval @failure_callback.try(:call, result.value, retry_count + 1) result = execute_protected blk @@ -43,7 +45,9 @@ class RetryService private def execute_protected blk - Result.ok(blk.()) + result = blk.() + return result if Result === result + Result.ok(result) rescue Exception => e if @registered_exceptions.any?{ |re| e.is_a? re } Result.error(e) @@ -51,4 +55,9 @@ class RetryService raise end end + + def warn message + return unless @logger + @logger.try :warn, message + end end diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index f91093806..d06d4607c 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -31,23 +31,17 @@ class WorkbenchImportWorker host: export_host, path: export_path, token: token(eg_name), - params: params, - upload: {file: [eg_file, 'application/zip', eg_name]}) + params: params(eg_file, eg_name)) end def log_failure reason, count logger.warn "HTTP POST failed with #{reason}, count = #{count}, response=#{@response}" end - def try_again - raise RetryService::Retry - end - def try_upload_entry_group eg_name, eg_file result = execute_post eg_name, eg_file - return result if result && result.status < 400 - @response = result.body - try_again + return Result.ok(result) if result && result.status < 400 + Result.error(JSON.parse result.body) end def upload zip_service @@ -63,6 +57,7 @@ class WorkbenchImportWorker retry_service = RetryService.new( delays: RETRY_DELAYS, rescue_from: [HTTPService::Timeout], + logger: logger, &method(:log_failure)) status = retry_service.execute(&upload_entry_group_proc(entry_pair)) raise StopIteration unless status.ok? @@ -116,7 +111,11 @@ class WorkbenchImportWorker @__import_url__ ||= File.join(import_host, import_path) end - def params - @__params__ ||= { netex_import: { referential_id: @workbench_import.referential_id, workbench_id: @workbench_import.workbench_id } } + def params file, name + { netex_import: + { referential_id: @workbench_import.referential_id, + workbench_id: @workbench_import.workbench_id, + name: name, + file: HTTPService.upload(file, 'application/zip', name) } } end end diff --git a/spec/models/concerns/error_format_spec.rb b/spec/models/concerns/error_format_spec.rb new file mode 100644 index 000000000..7f7df22b6 --- /dev/null +++ b/spec/models/concerns/error_format_spec.rb @@ -0,0 +1,35 @@ +RSpec.describe ErrorFormat do + + context '#details' do + context 'are empty' do + it 'if no errors are present' do + expect( described_class.details(create :referential) ).to be_empty + end + + it 'if no validation has been carried out' do + invalid = build :referential, name: nil + expect( described_class.details(invalid) ).to be_empty + end + end + + context 'are not empty' do + it 'if an error is present and validation has been carried out' do + invalid = build :referential, name: nil + expect( invalid ).not_to be_valid + expect( described_class.details(invalid) ).to eq([ + {name: {error: 'doit ĂȘtre rempli(e)', value: nil}} + ]) + end + + it 'and can even hold many errors' do + create :referential, name: 'hello' + invalid = build :referential, name: 'hello', slug: 'hello world' + expect( invalid ).not_to be_valid + expect( described_class.details(invalid) ).to eq([ + {name: {error: "n'est pas disponible", value: 'hello'}}, + {slug: {error: "n'est pas valide", value: 'hello world'}} + ]) + end + end + end +end |
