From b4e192a80ff317c379a6cbc08d9ce1f0f32ba183 Mon Sep 17 00:00:00 2001 From: Bogdan Marc Date: Wed, 11 Dec 2024 13:55:44 +0000 Subject: [PATCH 01/33] Fixed undefined var or method in ReportManagerApi --- app/services/report_manager_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index c730a56..5cdacd7 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -178,7 +178,7 @@ def log_api_response(response, start_time, url: nil, status: nil, message: '') case response_status when 500..599 - log_fields[:message] = env['action_dispatch.exception'] + log_fields[:message] = response.env['action_dispatch.exception'] Rails.logger.error(JSON.generate(log_fields)) when 400..499 Rails.logger.warn(JSON.generate(log_fields)) From 3db7ac34c7add7e9e39ef8dc8e0d7bf20d052b1b Mon Sep 17 00:00:00 2001 From: Bogdan Marc Date: Wed, 11 Dec 2024 13:55:54 +0000 Subject: [PATCH 02/33] Bumped app version --- app/lib/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/version.rb b/app/lib/version.rb index da348ad..4d205e6 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -3,7 +3,7 @@ module Version MAJOR = 2 MINOR = 0 - PATCH = 0 + PATCH = 1 SUFFIX = nil VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}" end From 6df653cea6bec61c66ea9d03ec514ab5da8f8fc2 Mon Sep 17 00:00:00 2001 From: Bogdan Marc Date: Wed, 11 Dec 2024 13:56:03 +0000 Subject: [PATCH 03/33] Added changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f65d82..c2c460f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Standard Reports UI: change log +## 2.0.1 - 2024-12 + +- (Bogdan) Fixed a bug that was causing an internal application error in `ReportManagerApi` + ## 2.0.0 - 2024-12 - (Bogdan) Updated all gems by regenerating `Gemfile.lock` From d887de84093a9120c69e6c99c2557e2582bd9f09 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 16 Dec 2024 17:00:56 +0000 Subject: [PATCH 04/33] fix: remove error instrumentation from standard error handling --- app/controllers/application_controller.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 31e9aca..8390e7e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,8 +27,6 @@ def log_request_result # or attempt to render a generic error page if no specific error page exists unless Rails.application.config.consider_all_requests_local rescue_from StandardError do |e| - # Instrument ActiveSupport::Notifications for internal errors: - ActiveSupport::Notifications.instrument('internal_error.application', exception: e) # Trigger the appropriate error handling method based on the exception case e.class when ActionController::RoutingError, ActionView::MissingTemplate From 93545f7d11600c68731b6135c708cd586d2a6a19 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 16 Dec 2024 17:01:17 +0000 Subject: [PATCH 05/33] fix: only trigger instrumentation on internal errors --- app/controllers/application_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8390e7e..160cb2b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -47,6 +47,8 @@ def handle_internal_error(exception) render_error(400) else Rails.logger.warn "No explicit error page for exception #{exception} - #{exception.class}" + # Instrument ActiveSupport::Notifications for internal server errors only: + instrument_internal_error(exception) render_error(500) end end From 94542b455bda0578215ec7f92c2110dde151ce3c Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 16 Dec 2024 17:01:38 +0000 Subject: [PATCH 06/33] fix: improve error metrics reporting - ensures that logging always happens with the appropriate severity depending on the exception status - reduces the types of errors that can trigger a an error metric and therefore a notification in slack (e.g. :bad_request is set at WARN level and therefore not alerted on, whereas :internal_server_error is set at ERROR level and does trigger alerts --- app/controllers/application_controller.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 160cb2b..a77c0d4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -118,4 +118,26 @@ def detailed_request_log(duration) end end # rubocop:enable Metrics/AbcSize, Metrics/MethodLength + + # Notify subscriber(s) of an internal error event with the payload of the + # exception once done + # @param [exc] exp the exception that caused the error + # @return [ActiveSupport::Notifications::Event] provides an object-oriented + # interface to the event + def instrument_internal_error(exc) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + err = { + message: exc&.message || exc, + status: exc&.status || Rack::Utils::SYMBOL_TO_STATUS_CODE[exc] + } + err[:type] = exc.class&.name if exc&.class + err[:cause] = exc&.cause if exc&.cause + err[:backtrace] = exc&.backtrace if exc&.backtrace && Rails.env.development? + # Log the exception to the Rails logger with the appropriate severity + Rails.logger.send(err[:status] < 500 ? :warn : :error, JSON.generate(err)) + # Return unless the status code is 500 or greater to ensure subscribers are NOT notified + return unless err[:status] >= 500 + + # Instrument the internal error event to notify subscribers of the error + ActiveSupport::Notifications.instrument('internal_error.application', exception: err) + end end From 2ae9978b038d5117b3b8c4913ea67ac41c919b1a Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 16 Dec 2024 17:02:14 +0000 Subject: [PATCH 07/33] fix: removes test environment from sentry --- config/initializers/sentry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 8c596e9..6e957bc 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -6,7 +6,7 @@ Sentry.init do |config| config.dsn = ENV['SENTRY_API_KEY'] config.environment = ENV.fetch('DEPLOYMENT_ENVIRONMENT') { Rails.env } - config.enabled_environments = %w[production test] + config.enabled_environments = %w[production] config.release = Version::VERSION config.breadcrumbs_logger = %i[active_support_logger http_logger] config.excluded_exceptions += ['ActionController::BadRequest'] From 4eccd15b75e3e2a28ea9d50253e27aeefc0266ee Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:13:25 +0000 Subject: [PATCH 08/33] style: Return `false` instead of `nil` in predicate methods also align the operands of a condition in an `unless` statement spanning multiple lines --- app/services/report_manager.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/services/report_manager.rb b/app/services/report_manager.rb index 4e6f2f9..89dae5b 100644 --- a/app/services/report_manager.rb +++ b/app/services/report_manager.rb @@ -113,15 +113,17 @@ def validate?(params) end def key_present?(params, key) - return unless !params.key?(key) || params[key].nil? || params[key].to_s.empty? + return false unless !params.key?(key) || params[key].nil? || params[key].to_s.empty? @errors ||= [] @errors << "missing parameter #{key}" end def array_key_present?(params, key) - return unless !params.key?(key) || params[key].nil? || - !params[key].is_a?(Array) || params[key].empty? + return false unless !params.key?(key) || + params[key].nil? || + !params[key].is_a?(Array) || + params[key].empty? @errors ||= [] @errors << "missing parameter #{key}" @@ -131,7 +133,7 @@ def valid_postcodes?(params) area = params[:area] pattern = validation_pattern(params) - return unless pattern && !pattern.match?(area) + return false unless pattern && !pattern.match?(area) @errors ||= [] @errors << 'invalid postal code' From c645381d4c97f336fad8be44542f3d35ecb5d891 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:14:35 +0000 Subject: [PATCH 09/33] fix: add fallbacks to current date if spec not available prevents unknown method errors if nil --- app/services/report_manager.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/services/report_manager.rb b/app/services/report_manager.rb index 89dae5b..13bc35f 100644 --- a/app/services/report_manager.rb +++ b/app/services/report_manager.rb @@ -17,11 +17,15 @@ def initialize(config = nil) end def latest_month - latest_month_spec.split('-').second.to_i + # with fallback to current month if not available + month = latest_month_spec&.split('-') || Time.zone.today.strftime('%Y-%m').split('-') + month.second.to_i end def latest_year - latest_month_spec.split('-').first.to_i + # with fallback to current year if not available + year = latest_month_spec&.split('-') || Time.zone.today.strftime('%Y-%m').split('-') + year&.first.to_i end def latest_quarter From eaf6775b33c996acdbc0ea31dbc66eadcf023dd2 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:15:29 +0000 Subject: [PATCH 10/33] style: disabled rubocop warnings - `Metrics/MethodLength` - `Metrics/CyclomaticComplexity` --- app/services/report_manager.rb | 2 +- app/services/report_manager_api.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/services/report_manager.rb b/app/services/report_manager.rb index 13bc35f..f0935d6 100644 --- a/app/services/report_manager.rb +++ b/app/services/report_manager.rb @@ -78,7 +78,7 @@ def start_requests(params) # a=1&b[]=2&b[]=3 # becomes # [{a: 1, b: 2}, {a: 1, b: 3}] - def create_params_sets(params) + def create_params_sets(params) # rubocop:disable Metrics/MethodLength product = [{}] params.each do |k, v| diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 5cdacd7..b49584d 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Encapsulates the HTTP API for the report manager -class ReportManagerApi +class ReportManagerApi # rubocop:disable Metrics/ClassLength attr_reader :instrumenter def initialize(instrumenter = ActiveSupport::Notifications) @@ -39,7 +39,7 @@ def get(http_url, options = {}) private - def get_from_api(http_url, options) + def get_from_api(http_url, options) # rubocop:disable Metrics/MethodLength conn = set_connection_timeout(create_http_connection(http_url)) conn.get do |req| @@ -65,7 +65,7 @@ def load_status_report(response) # Parse the given JSON string into a data structure. Throws an exception if # parsing fails - def parse_json(json) + def parse_json(json) # rubocop:disable Metrics/MethodLength result = nil json_hash = parser.parse(StringIO.new(json)) do |json_chunk| @@ -143,7 +143,7 @@ def record_api_error_response(http_url, method, response, start_time) throw error_message end - def record_api_ok_response(http_url, method, response, start_time) + def record_api_ok_response(http_url, method, response, start_time) # rubocop:disable Metrics/MethodLength end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time success_message = "API #{method} to '#{http_url}' succeeded: '#{response.body}'" @@ -162,7 +162,7 @@ def record_failed_connection(http_url, exception) throw "Failed to connect to '#{http_url}'" end - # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity def log_api_response(response, start_time, url: nil, status: nil, message: '') end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time @@ -186,5 +186,5 @@ def log_api_response(response, start_time, url: nil, status: nil, message: '') Rails.logger.info(JSON.generate(log_fields)) end end - # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity end From ab26367f227c30fc5c01bd019d2e02af9aefc7ab Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:21:25 +0000 Subject: [PATCH 11/33] fix: check for response first --- app/services/report_manager_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index b49584d..898d020 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -109,7 +109,7 @@ def set_connection_timeout(conn) # rubocop:disable Naming/AccessorMethodName end def ok?(response) - (200..207).cover?(response.status) + (200..207).cover?(response.status) if response end def as_http_api(api) From e24515cb21a17fb69a5635f07bfcaa0b7a4a2a7e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:22:34 +0000 Subject: [PATCH 12/33] fix: updated message and removed underscore from variable that's used --- app/services/report_manager_api.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 898d020..1a28747 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -120,11 +120,10 @@ def parser @parser ||= Yajl::Parser.new end - def report_json_failure(_json) - msg = 'JSON result was not parsed correctly' + def report_json_failure(json) + msg = "Failed to parse JSON: #{json.inspect}" Sentry.capture_message(msg) Rails.logger.error(msg) - throw msg end def record_api_error_response(http_url, method, response, start_time) From 0a79e0e5768d69bab3565b8812bc49183968f80d Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:24:26 +0000 Subject: [PATCH 13/33] fix: ensure correct instrumentation for error now triggers `api_service_exception` metric on error --- app/services/report_manager_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 1a28747..ce2b6bc 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -137,7 +137,7 @@ def record_api_error_response(http_url, method, response, start_time) status: response.status, message: error_message ) - instrumenter&.instrument('response.api', response: response, duration: ellapsed_time) + instrumenter&.instrument('service_exception.api', response: response, duration: ellapsed_time) throw error_message end From 10ddf7f05d6dfe7b0b27ef83c7664e65983c314f Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:28:07 +0000 Subject: [PATCH 14/33] fix: Replace specific fields when available --- app/services/report_manager_api.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index ce2b6bc..6f18a30 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -167,17 +167,20 @@ def log_api_response(response, start_time, url: nil, status: nil, message: '') ellapsed_time = end_time - start_time log_fields = { - url: response ? response.env[:url].to_s : url, - status: status || response.status, + url: url, duration: ellapsed_time, + status: status, message: message } + # Replace specific fields if available in the response + log_fields[:url] = response.env[:url].to_s if response + log_fields[:status] = response.status if response + log_fields[:message] = response.body if response - response_status = response ? response.status : status - - case response_status + case log_fields[:status] when 500..599 - log_fields[:message] = response.env['action_dispatch.exception'] + exp = response.env['action_dispatch.exception'] || response.env['exception'] + log_fields[:message] = exp.message if exp Rails.logger.error(JSON.generate(log_fields)) when 400..499 Rails.logger.warn(JSON.generate(log_fields)) From 06f1ab5dd915fb7bede5369faee0c32d4635acca Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:29:52 +0000 Subject: [PATCH 15/33] fix: utilise safeNavigation to remove `NoMethodError for nil` errors --- app/services/report_manager_api.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 6f18a30..37e632b 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -129,12 +129,14 @@ def report_json_failure(json) def record_api_error_response(http_url, method, response, start_time) end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time - error_message = "API #{method} to '#{http_url}' failed: '#{response.body}'" + body = response&.body + status = response&.status + error_message = "API #{method} to '#{http_url}' failed: '#{body}'" log_api_response( response, start_time, url: http_url, - status: response.status, + status: status, message: error_message ) instrumenter&.instrument('service_exception.api', response: response, duration: ellapsed_time) From f7648566abc97822c00b92a32702bafb8c379563 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:30:35 +0000 Subject: [PATCH 16/33] fix: don't throw unless it will be caught! --- app/services/report_manager_api.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 37e632b..1470d63 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -140,8 +140,6 @@ def record_api_error_response(http_url, method, response, start_time) message: error_message ) instrumenter&.instrument('service_exception.api', response: response, duration: ellapsed_time) - - throw error_message end def record_api_ok_response(http_url, method, response, start_time) # rubocop:disable Metrics/MethodLength @@ -160,7 +158,6 @@ def record_api_ok_response(http_url, method, response, start_time) # rubocop:dis def record_failed_connection(http_url, exception) instrumenter&.instrument('connection_failure.api', exception: exception, url: http_url) - throw "Failed to connect to '#{http_url}'" end # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity From a58562fa7dd9f0e5c332f97d7dbb325593d6d5e5 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:31:15 +0000 Subject: [PATCH 17/33] style: disabled rubocop Metrics/MethodLength warning --- app/services/report_manager_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 1470d63..6290e16 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -126,7 +126,7 @@ def report_json_failure(json) Rails.logger.error(msg) end - def record_api_error_response(http_url, method, response, start_time) + def record_api_error_response(http_url, method, response, start_time) # rubocop:disable Metrics/MethodLength end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time body = response&.body From b75fb80329c2110258d681d7803b7731e2c8f485 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:32:22 +0000 Subject: [PATCH 18/33] fix: resolve missing error templates update to use `Rails.public_path` alongside ending the path with `.html` to be sure --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a77c0d4..9c6f182 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -81,7 +81,7 @@ def render_error(status) def render_html_error_page(status) render(layout: true, - file: Rails.root.join('public', 'landing', status.to_s), + file: Rails.public_path + "landing/#{status}.html", status: status) end From c73ac29d265d445c3facc5e03ed1060adf2f76f6 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:32:55 +0000 Subject: [PATCH 19/33] build: updated Makefile to mirror use across company --- Makefile | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 166f9c9..402fbc7 100644 --- a/Makefile +++ b/Makefile @@ -37,8 +37,9 @@ ${GITHUB_TOKEN}: all: image assets: auth - @./bin/bundle config set --local without 'development test' + @echo "Installing all packages ..." @./bin/bundle install + @echo "Cleaning up precompiled assets ..." @./bin/rails assets:clean assets:precompile auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} @@ -68,12 +69,6 @@ image: auth lint: assets @./bin/bundle exec rubocop -local: - @echo "Installing all packages ..." - @./bin/bundle install - @echo "Starting local server ..." - @./bin/rails server -p ${PORT} - publish: image @echo Publishing image: ${REPO}:${TAG} ... @docker push ${REPO}:${TAG} 2>&1 @@ -86,7 +81,7 @@ run: start @if docker network inspect dnet > /dev/null 2>&1; then echo "Using docker network dnet"; else echo "Create docker network dnet"; docker network create dnet; sleep 2; fi @docker run -p ${PORT}:3000 -e API_SERVICE_URL=${API_SERVICE_URL} --network dnet --rm --name ${SHORTNAME} ${REPO}:${TAG} -server: assets start +server: @export SECRET_KEY_BASE=$(./bin/rails secret) @API_SERVICE_URL=${API_SERVICE_URL} ./bin/rails server -p ${PORT} From b48841413cf44a8d4f0a00d1b142f55ba596a11e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:38:25 +0000 Subject: [PATCH 20/33] docs: updated CHANGELOG --- CHANGELOG.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2c460f..4892671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,21 @@ # Standard Reports UI: change log +## 2.0.2 - 2024-12 + +- (Jon) Myriad of tweaks to ensure variables either fail quietly via safe + navigation or are set to a default value to prevent errors in the application +- (Jon) Updated the error template path to use `Rails.public_path` as well as + contain the `html` extension to ensure the correct template is rendered +- (Jon) Improves error metrics reporting to ensure that logging always happens + with the appropriate severity depending on the exception status while reducing + the types of errors that can trigger a an error metric and therefore a + notification in slack + [GH-149](https://github.com/epimorphics/hmlr-linked-data/issues/149) + ## 2.0.1 - 2024-12 -- (Bogdan) Fixed a bug that was causing an internal application error in `ReportManagerApi` +- (Bogdan) Fixed a bug that was causing an internal application error in + `ReportManagerApi` ## 2.0.0 - 2024-12 @@ -13,7 +26,8 @@ ## 1.6.0 - 2024-10 -- (Dan) Updates ruby version to 2.7.8 and alpine version to 3.16 [GH-143](https://github.com/epimorphics/standard-reports-ui/issues/143) +- (Dan) Updates ruby version to 2.7.8 and alpine version to 3.16 + [GH-143](https://github.com/epimorphics/standard-reports-ui/issues/143) ## 1.5.4 - 2024-09 From 444885ced4a837b5babb707e30cf4191ef357912 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 09:38:38 +0000 Subject: [PATCH 21/33] build: updated patch version cadence --- app/lib/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/version.rb b/app/lib/version.rb index 4d205e6..d77e6b5 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -3,7 +3,7 @@ module Version MAJOR = 2 MINOR = 0 - PATCH = 1 + PATCH = 2 SUFFIX = nil VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}" end From 64b41e2db9d5b012dfd840bd15ef72029b653e0d Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 10:38:29 +0000 Subject: [PATCH 22/33] fix: improved error handling on api response Emits logs with specific message and error to help pinpoint --- app/services/report_manager.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/services/report_manager.rb b/app/services/report_manager.rb index f0935d6..96c34f1 100644 --- a/app/services/report_manager.rb +++ b/app/services/report_manager.rb @@ -17,19 +17,24 @@ def initialize(config = nil) end def latest_month - # with fallback to current month if not available - month = latest_month_spec&.split('-') || Time.zone.today.strftime('%Y-%m').split('-') - month.second.to_i + latest_month_spec && latest_month_spec.split('-').second.to_i + rescue StandardError => e + msg = "Failed to retreive latest month from #{url}latest-month-available" + Rails.logger.error { "#{msg}: #{e}" } end def latest_year - # with fallback to current year if not available - year = latest_month_spec&.split('-') || Time.zone.today.strftime('%Y-%m').split('-') - year&.first.to_i + latest_month_spec && latest_month_spec.split('-').first.to_i + rescue StandardError => e + msg = "Failed to retreive latest year from #{url}latest-month-available" + Rails.logger.error { "#{msg}: #{e}" } end def latest_quarter - (latest_month / 3).to_i + latest_month && (latest_month / 3).to_i + rescue StandardError => e + msg = "Failed to retreive latest quarter from #{url}latest-month-available" + Rails.logger.error { "#{msg}: #{e}" } end def latest_month_spec From bf33345f6558f4a5bc1e12b8c28286e2acbd3482 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 10:39:23 +0000 Subject: [PATCH 23/33] style: improved log message and additional rubocop linting fixes --- app/services/report_manager.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/services/report_manager.rb b/app/services/report_manager.rb index 96c34f1..ebb838b 100644 --- a/app/services/report_manager.rb +++ b/app/services/report_manager.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Service object for interacting with remote service-manager API -class ReportManager +class ReportManager # rubocop:disable Metrics/ClassLength def initialize(config = nil) return unless config @@ -104,7 +104,7 @@ def create_params_sets(params) # rubocop:disable Metrics/MethodLength def start_request(req_spec) json = api.post_json("#{url}report-request", req_spec.to_hash) - Rails.logger.debug { "ReportManager: #{json}" } if Rails.env.development? + Rails.logger.debug { "ReportManager response: #{json}" } if Rails.env.development? ReportStatus.new(json) end @@ -122,7 +122,9 @@ def validate?(params) end def key_present?(params, key) - return false unless !params.key?(key) || params[key].nil? || params[key].to_s.empty? + return false unless !params.key?(key) || + params[key].nil? || + params[key].to_s.empty? @errors ||= [] @errors << "missing parameter #{key}" From 353d32ed136d583bfe174f6f2b3d5149cb5dd00b Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 10:49:49 +0000 Subject: [PATCH 24/33] style: rubocop linting autofixes --- app/lib/version.rb | 2 +- app/models/step_select_dates.rb | 4 ++-- app/models/step_select_postcode_area.rb | 2 +- app/models/step_select_postcode_district.rb | 2 +- app/models/step_select_postcode_sector.rb | 2 +- app/services/report_manager_api.rb | 6 +++--- app/subscribers/action_controller_prometheus_subscriber.rb | 4 ++-- config.ru | 2 +- config/initializers/load_notification_subscribers.rb | 2 +- config/initializers/prometheus.rb | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/lib/version.rb b/app/lib/version.rb index d77e6b5..0d741d6 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -5,5 +5,5 @@ module Version MINOR = 0 PATCH = 2 SUFFIX = nil - VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}" + VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}".freeze end diff --git a/app/models/step_select_dates.rb b/app/models/step_select_dates.rb index e2ee60c..16cd39a 100644 --- a/app/models/step_select_dates.rb +++ b/app/models/step_select_dates.rb @@ -51,10 +51,10 @@ def generic_name 'select dates' end - def each_year(hidden_only = true, &block) + def each_year(hidden_only = true, &) start_delta = hidden_only ? YEARS_SHOWN_BY_DEFAULT : 0 delta = Time.now.year - EARLIEST_YEAR - (start_delta..delta).each(&block) + (start_delta..delta).each(&) end private diff --git a/app/models/step_select_postcode_area.rb b/app/models/step_select_postcode_area.rb index 1c1fbc4..1c61865 100644 --- a/app/models/step_select_postcode_area.rb +++ b/app/models/step_select_postcode_area.rb @@ -2,7 +2,7 @@ # Workflow step of selecting a postcode area class StepSelectPostcodeArea < StepSelectPostcode - VALIDATION = /\A[A-Z][A-Z]?\Z/.freeze + VALIDATION = /\A[A-Z][A-Z]?\Z/ def initialize super(:select_pc_area) diff --git a/app/models/step_select_postcode_district.rb b/app/models/step_select_postcode_district.rb index 2c6a643..39db8fc 100644 --- a/app/models/step_select_postcode_district.rb +++ b/app/models/step_select_postcode_district.rb @@ -2,7 +2,7 @@ # Workflow step of selecting a postcode district class StepSelectPostcodeDistrict < StepSelectPostcode - VALIDATION = /\A[A-Z][A-Z]?[0-9][0-9]?[A-Z]?\Z/.freeze + VALIDATION = /\A[A-Z][A-Z]?[0-9][0-9]?[A-Z]?\Z/ def initialize super(:select_pc_district) diff --git a/app/models/step_select_postcode_sector.rb b/app/models/step_select_postcode_sector.rb index 077437e..b03a3e3 100644 --- a/app/models/step_select_postcode_sector.rb +++ b/app/models/step_select_postcode_sector.rb @@ -2,7 +2,7 @@ # Workflow step of selecting a postcode sector class StepSelectPostcodeSector < StepSelectPostcode - VALIDATION = /\A[A-Z][A-Z]?[0-9][0-9]?[A-Z]? [0-9]\Z/.freeze + VALIDATION = /\A[A-Z][A-Z]?[0-9][0-9]?[A-Z]? [0-9]\Z/ def initialize super(:select_pc_sector) diff --git a/app/services/report_manager_api.rb b/app/services/report_manager_api.rb index 6290e16..8770b00 100644 --- a/app/services/report_manager_api.rb +++ b/app/services/report_manager_api.rb @@ -39,7 +39,7 @@ def get(http_url, options = {}) private - def get_from_api(http_url, options) # rubocop:disable Metrics/MethodLength + def get_from_api(http_url, options) conn = set_connection_timeout(create_http_connection(http_url)) conn.get do |req| @@ -126,7 +126,7 @@ def report_json_failure(json) Rails.logger.error(msg) end - def record_api_error_response(http_url, method, response, start_time) # rubocop:disable Metrics/MethodLength + def record_api_error_response(http_url, method, response, start_time) end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time body = response&.body @@ -142,7 +142,7 @@ def record_api_error_response(http_url, method, response, start_time) # rubocop: instrumenter&.instrument('service_exception.api', response: response, duration: ellapsed_time) end - def record_api_ok_response(http_url, method, response, start_time) # rubocop:disable Metrics/MethodLength + def record_api_ok_response(http_url, method, response, start_time) end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) ellapsed_time = end_time - start_time success_message = "API #{method} to '#{http_url}' succeeded: '#{response.body}'" diff --git a/app/subscribers/action_controller_prometheus_subscriber.rb b/app/subscribers/action_controller_prometheus_subscriber.rb index 2f557b9..881e5f8 100644 --- a/app/subscribers/action_controller_prometheus_subscriber.rb +++ b/app/subscribers/action_controller_prometheus_subscriber.rb @@ -7,7 +7,7 @@ class ActionControllerPrometheusSubscriber < ActiveSupport::Subscriber attach_to :action_controller - # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + # rubocop:disable Metrics/AbcSize def process_action(_event) mem = GetProcessMem.new Prometheus::Client.registry @@ -59,5 +59,5 @@ def process_action(_event) } ) end - # rubocop:enable Metrics/AbcSize, Metrics/MethodLength + # rubocop:enable Metrics/AbcSize end diff --git a/config.ru b/config.ru index a9e519f..4d43cee 100644 --- a/config.ru +++ b/config.ru @@ -2,7 +2,7 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('config/environment', __dir__) +require File.expand_path('config/environment', __dir__) unless Rails.env.test? require 'prometheus/middleware/collector' diff --git a/config/initializers/load_notification_subscribers.rb b/config/initializers/load_notification_subscribers.rb index d22a22f..924eeab 100644 --- a/config/initializers/load_notification_subscribers.rb +++ b/config/initializers/load_notification_subscribers.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -Dir[Rails.root.join('app/subscribers/**/*_subscriber.rb')].sort.each do |source| +Dir[Rails.root.join('app/subscribers/**/*_subscriber.rb')].each do |source| require source end diff --git a/config/initializers/prometheus.rb b/config/initializers/prometheus.rb index 648ed3b..eb79270 100644 --- a/config/initializers/prometheus.rb +++ b/config/initializers/prometheus.rb @@ -50,5 +50,5 @@ ) # Middleware instrumentation - # This fixes the 0 memory bug by notifying Action Dispatch subscribers on Prometheus initialise - ActiveSupport::Notifications.instrument('process_middleware.action_dispatch') +# This fixes the 0 memory bug by notifying Action Dispatch subscribers on Prometheus initialise +ActiveSupport::Notifications.instrument('process_middleware.action_dispatch') From 9c1e4736f063bd407fb3eb56b77749e9a2917bf4 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 10:58:14 +0000 Subject: [PATCH 25/33] fix: Prefer keyword arguments for arguments with a boolean default value also restores block to resolve unexpected token tRPAREN error as well as sets Time.now.year to Time.current.year to ensure zone is incorporated in calculations --- app/models/step_select_dates.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/step_select_dates.rb b/app/models/step_select_dates.rb index 16cd39a..e49f7d2 100644 --- a/app/models/step_select_dates.rb +++ b/app/models/step_select_dates.rb @@ -51,10 +51,10 @@ def generic_name 'select dates' end - def each_year(hidden_only = true, &) + def each_year(hidden_only: true, &block) start_delta = hidden_only ? YEARS_SHOWN_BY_DEFAULT : 0 - delta = Time.now.year - EARLIEST_YEAR - (start_delta..delta).each(&) + delta = Time.current.year - EARLIEST_YEAR + (start_delta..delta).each(&block) end private From 7d493db76494ae56f8734ab90c7fb0e6eba528cb Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:00:44 +0000 Subject: [PATCH 26/33] fix: resolve `Metrics/CollectionLiteralLength` for long list of districts --- app/models/step_select_district.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/step_select_district.rb b/app/models/step_select_district.rb index 9625e15..f3c535a 100644 --- a/app/models/step_select_district.rb +++ b/app/models/step_select_district.rb @@ -23,7 +23,8 @@ def successor_step :select_aggregation_type end - NAMES = [ + # The names of all the districts + NAMES = [ # rubocop:disable Metrics/CollectionLiteralLength 'ADUR', 'ALLERDALE', 'AMBER VALLEY', From 934468d7577f37d00d1e2fd083a159add977e3b1 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:03:43 +0000 Subject: [PATCH 27/33] fix: Use `tag.div` instead of `tag(:div)`. (convention:Rails/ContentTag) --- app/helpers/report_design_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/report_design_helper.rb b/app/helpers/report_design_helper.rb index dca7805..1ed922a 100644 --- a/app/helpers/report_design_helper.rb +++ b/app/helpers/report_design_helper.rb @@ -218,7 +218,7 @@ def show_change_link(workflow, step) def layout_map_control(_step) content_tag(:div, class: 'col-sm-12 col-md-6') do - tag(:div, id: 'map', class: 'o-map') + tag.div(id: 'map', class: 'o-map') end end end From acff13171d3604b6f8c318bd359de74795eb1055 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:04:48 +0000 Subject: [PATCH 28/33] fix: sets Time.now to Time.current to ensure zone is in calculations --- app/helpers/report_design_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/report_design_helper.rb b/app/helpers/report_design_helper.rb index 1ed922a..5f0dcd0 100644 --- a/app/helpers/report_design_helper.rb +++ b/app/helpers/report_design_helper.rb @@ -116,7 +116,7 @@ def selected_area_summary(workflow) end def layout_custom_dates(delta, step, workflow) - year = Time.now.year - delta + year = Time.current.year - delta content_tag(:div, class: 'row') do concat(content_tag(:div, class: 'col-sm-12 col-md-1') do content_tag(:h3, year.to_s, class: 'u-font-bold u-align-top') @@ -130,7 +130,7 @@ def layout_custom_dates(delta, step, workflow) end def layout_all_year(step, year, workflow) - all_year = year == Time.now.year ? 'to date' : 'all year' + all_year = year == Time.current.year ? 'to date' : 'all year' checked = workflow.has_state?(step.param_name, year.to_s) capture do concat prompted_row( From 392e0dc038676d5a48113a5a11c178f4169681f4 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:05:48 +0000 Subject: [PATCH 29/33] style: disabling rubocop linting warnings --- app/helpers/download_request_helper.rb | 2 +- app/helpers/report_design_helper.rb | 10 +++++----- app/models/report_specification.rb | 2 +- app/models/step_select_aggregation_type.rb | 2 +- app/models/workflow.rb | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/helpers/download_request_helper.rb b/app/helpers/download_request_helper.rb index bd33ba8..0c5c1e9 100644 --- a/app/helpers/download_request_helper.rb +++ b/app/helpers/download_request_helper.rb @@ -12,7 +12,7 @@ def render_report_request(request) end end - def request_status(request) + def request_status(request) # rubocop:disable Metrics/MethodLength capture do if request.unknown? concat render_unknown_request(request) diff --git a/app/helpers/report_design_helper.rb b/app/helpers/report_design_helper.rb index 5f0dcd0..68f164d 100644 --- a/app/helpers/report_design_helper.rb +++ b/app/helpers/report_design_helper.rb @@ -2,7 +2,7 @@ # :nodoc: module ReportDesignHelper # rubocop:disable Metrics/ModuleLength - def workflow_step_form(workflow) # rubocop:disable Metrics/AbcSize + def workflow_step_form(workflow) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength step = workflow.current_step form_tag(workflow.form_action, method: 'get') do @@ -51,7 +51,7 @@ def layout_values_as_toggle_buttons(step, values, radio, cls = '') end end - def toggle_button_option(step, value, radio, single_value) + def toggle_button_option(step, value, radio, single_value) # rubocop:disable Metrics/MethodLength active = value.active? || single_value content_tag(:div, class: 'o-form-control') do @@ -115,7 +115,7 @@ def selected_area_summary(workflow) .summarise_current_value(workflow) end - def layout_custom_dates(delta, step, workflow) + def layout_custom_dates(delta, step, workflow) # rubocop:disable Metrics/MethodLength year = Time.current.year - delta content_tag(:div, class: 'row') do concat(content_tag(:div, class: 'col-sm-12 col-md-1') do @@ -147,7 +147,7 @@ def layout_months(step, year, workflow) layout_quarters_or_months(step.months_for(year, workflow), 'months', "#{step.param_name}[]") end - def layout_quarters_or_months(mqs, _prompt, param_name) + def layout_quarters_or_months(mqs, _prompt, param_name) # rubocop:disable Metrics/MethodLength capture do concat prompted_row( lambda { @@ -202,7 +202,7 @@ def review_selections(workflow) def review_selection(workflow, step) content_tag(:li) do - concat step.summarise(workflow.state(step.param_name)).html_safe + concat step.summarise(workflow.state(step.param_name)).html_safe # rubocop:disable Rails/OutputSafety concat show_change_link(workflow, step) end end diff --git a/app/models/report_specification.rb b/app/models/report_specification.rb index 23c4b28..f76d805 100644 --- a/app/models/report_specification.rb +++ b/app/models/report_specification.rb @@ -28,7 +28,7 @@ def normalize_period(report_manager) end end - def latest_quarter(report_manager) + def latest_quarter(report_manager) # rubocop:disable Metrics/MethodLength case report_manager.latest_month when 1..2 "#{report_manager.latest_year - 1}-Q4" diff --git a/app/models/step_select_aggregation_type.rb b/app/models/step_select_aggregation_type.rb index 3bb90f7..d3e32d9 100644 --- a/app/models/step_select_aggregation_type.rb +++ b/app/models/step_select_aggregation_type.rb @@ -14,7 +14,7 @@ def initialize super(:select_aggregation_type, :aggregate, :radio) end - def values_options(workflow) # rubocop:disable Metrics/CyclomaticComplexity + def values_options(workflow) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength case workflow.state(:areaType) when 'country' [AGGREGATE_BY_REGION, AGGREGATE_BY_COUNTY, AGGREGATE_BY_DISTRICT, diff --git a/app/models/workflow.rb b/app/models/workflow.rb index f64445d..b0e3597 100644 --- a/app/models/workflow.rb +++ b/app/models/workflow.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Model encapsulating the report-generation workflow -class Workflow +class Workflow # rubocop:disable Metrics/ClassLength extend Forwardable attr_reader :step_history From 553dc0a21b288099bf413a6bb0b1495e9bfee363 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:08:22 +0000 Subject: [PATCH 30/33] style: rubocop auto removing of unnecessary disabling of rules --- app/helpers/report_design_helper.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/helpers/report_design_helper.rb b/app/helpers/report_design_helper.rb index 68f164d..c66d2ca 100644 --- a/app/helpers/report_design_helper.rb +++ b/app/helpers/report_design_helper.rb @@ -2,7 +2,7 @@ # :nodoc: module ReportDesignHelper # rubocop:disable Metrics/ModuleLength - def workflow_step_form(workflow) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def workflow_step_form(workflow) # rubocop:disable Metrics/AbcSize step = workflow.current_step form_tag(workflow.form_action, method: 'get') do @@ -115,7 +115,7 @@ def selected_area_summary(workflow) .summarise_current_value(workflow) end - def layout_custom_dates(delta, step, workflow) # rubocop:disable Metrics/MethodLength + def layout_custom_dates(delta, step, workflow) year = Time.current.year - delta content_tag(:div, class: 'row') do concat(content_tag(:div, class: 'col-sm-12 col-md-1') do @@ -147,7 +147,7 @@ def layout_months(step, year, workflow) layout_quarters_or_months(step.months_for(year, workflow), 'months', "#{step.param_name}[]") end - def layout_quarters_or_months(mqs, _prompt, param_name) # rubocop:disable Metrics/MethodLength + def layout_quarters_or_months(mqs, _prompt, param_name) capture do concat prompted_row( lambda { @@ -202,7 +202,7 @@ def review_selections(workflow) def review_selection(workflow, step) content_tag(:li) do - concat step.summarise(workflow.state(step.param_name)).html_safe # rubocop:disable Rails/OutputSafety + concat step.summarise(workflow.state(step.param_name)).html_safe concat show_change_link(workflow, step) end end From 4f86b3dfc72c513e04a43c60dd777f0b38c5027b Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:14:21 +0000 Subject: [PATCH 31/33] style: disable rubocop `Style/ArgumentsForwarding` as otherwise ruby throws `unexpected token tRPAREN` error --- app/models/step_select_dates.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/step_select_dates.rb b/app/models/step_select_dates.rb index e49f7d2..6ab1f98 100644 --- a/app/models/step_select_dates.rb +++ b/app/models/step_select_dates.rb @@ -51,10 +51,10 @@ def generic_name 'select dates' end - def each_year(hidden_only: true, &block) + def each_year(hidden_only: true, &block) # rubocop:disable Style/ArgumentsForwarding start_delta = hidden_only ? YEARS_SHOWN_BY_DEFAULT : 0 delta = Time.current.year - EARLIEST_YEAR - (start_delta..delta).each(&block) + (start_delta..delta).each(&block) # rubocop:disable Style/ArgumentsForwarding end private From da32d306482d780ed9b46f8e870d7bcd808f3ad8 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 18 Dec 2024 11:15:02 +0000 Subject: [PATCH 32/33] style: disable rubocop `Metrics/MethodLength` warning --- app/models/step_select_dates.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/step_select_dates.rb b/app/models/step_select_dates.rb index 6ab1f98..919bd15 100644 --- a/app/models/step_select_dates.rb +++ b/app/models/step_select_dates.rb @@ -95,7 +95,7 @@ def latest_values(workflow) ] end - def summarise_value + def summarise_value # rubocop:disable Metrics/MethodLength proc { |state_value| s = case state_value.to_sym when :ytd From efa820d262c5b9303d41957140ca59ed81234347 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Fri, 20 Dec 2024 10:00:11 +0000 Subject: [PATCH 33/33] Update step_select_dates.rb Resolves WSOD on step 5 of 7 --- app/models/step_select_dates.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/step_select_dates.rb b/app/models/step_select_dates.rb index 919bd15..2e5a99e 100644 --- a/app/models/step_select_dates.rb +++ b/app/models/step_select_dates.rb @@ -51,10 +51,10 @@ def generic_name 'select dates' end - def each_year(hidden_only: true, &block) # rubocop:disable Style/ArgumentsForwarding + def each_year(hidden_only = true, &block) # rubocop:disable Style/OptionalBooleanParameter start_delta = hidden_only ? YEARS_SHOWN_BY_DEFAULT : 0 delta = Time.current.year - EARLIEST_YEAR - (start_delta..delta).each(&block) # rubocop:disable Style/ArgumentsForwarding + (start_delta..delta).each(&block) end private