aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/api/v1/netex_imports_controller.rb5
-rw-r--r--app/controllers/support/error_format.rb15
-rw-r--r--app/models/concerns/error_format.rb25
-rw-r--r--app/services/http_service.rb15
-rw-r--r--app/services/retry_service.rb13
-rw-r--r--app/workers/workbench_import_worker.rb21
-rw-r--r--spec/models/concerns/error_format_spec.rb35
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