Class: Lighthouse::ServiceException
- Inherits:
-
Object
- Object
- Lighthouse::ServiceException
- Extended by:
- SentryLogging
- Defined in:
- lib/lighthouse/service_exception.rb
Overview
Custom exception that maps Lighthouse API errors to controller ExceptionHandling-friendly format
Constant Summary collapse
- ERROR_MAP =
a map of the known Lighthouse errors based on the documentation developer.va.gov/
{ 504 => Common::Exceptions::GatewayTimeout, 503 => Common::Exceptions::ServiceUnavailable, 502 => Common::Exceptions::BadGateway, 501 => Common::Exceptions::NotImplemented, 500 => Common::Exceptions::ExternalServerInternalServerError, 499 => Common::Exceptions::ClientDisconnected, 429 => Common::Exceptions::TooManyRequests, 422 => Common::Exceptions::UnprocessableEntity, 413 => Common::Exceptions::PayloadTooLarge, 404 => Common::Exceptions::ResourceNotFound, 403 => Common::Exceptions::Forbidden, 401 => Common::Exceptions::Unauthorized, 400 => Common::Exceptions::BadRequest }.freeze
Class Method Summary collapse
-
.error_class(status_code) ⇒ Object
chooses which error class should be reported based on the http status.
-
.error_object_details(error_body, status_code) ⇒ Object
error details that match the evss_errors response schema uses known fields in the Lighthouse errors such as “title”, “code”, “detail”, “message”, “error” used to get more information from Lighthouse errors in the controllers.
-
.get_errors_from_response(error, status_code) ⇒ Object
extracts and transforms Lighthouse errors into the evss_errors schema for the controller ExceptionHandling class.
- .get_status_code(response) ⇒ Object
- .json_response?(response) ⇒ Boolean
- .log_to_rails_logger(service_name, options) ⇒ Object
- .missing_http_status_server_error(error) ⇒ Object
- .response_type(response) ⇒ Object
-
.send_error(error, service_name, lighthouse_client_id, url, options = {}) ⇒ Object
sends error logs to sentry that contains the client id and url that the consumer was trying call raises an error based off of what the response status was formats the Lighthouse exception for the controller ExceptionHandling to report out to the consumer.
-
.send_error_logs(error, service_name, lighthouse_client_id, url, options = {}) ⇒ Object
log errors.
-
.transform_error_keys(error_body, status, title, detail, code) ⇒ Object
transform error hash keys into symbols for controller ExceptionHandling class.
Methods included from SentryLogging
log_exception_to_sentry, log_message_to_sentry, non_nil_hash?, normalize_level, rails_logger, set_sentry_metadata
Class Method Details
.error_class(status_code) ⇒ Object
chooses which error class should be reported based on the http status
54 55 56 57 58 |
# File 'lib/lighthouse/service_exception.rb', line 54 def self.error_class(status_code) return Common::Exceptions::ServiceError unless ERROR_MAP.include?(status_code) ERROR_MAP[status_code] end |
.error_object_details(error_body, status_code) ⇒ Object
error details that match the evss_errors response schema uses known fields in the Lighthouse errors such as “title”, “code”, “detail”, “message”, “error” used to get more information from Lighthouse errors in the controllers
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/lighthouse/service_exception.rb', line 83 def self.error_object_details(error_body, status_code) status = status_code.to_s title = error_body['title'] || error_class(status_code).to_s detail = error_body['detail'] || error_body['message'] || error_body['error'] || error_body['error_description'] || 'No details provided' code = error_body['code'] || status [status, title, detail, code] end |
.get_errors_from_response(error, status_code) ⇒ Object
extracts and transforms Lighthouse errors into the evss_errors schema for the controller ExceptionHandling class
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/lighthouse/service_exception.rb', line 62 def self.get_errors_from_response(error, status_code) errors = error.response[:body]['errors'] if errors&.any? errors.map do |e| status, title, detail, code = error_object_details(e, status_code) transform_error_keys(e, status, title, detail, code) end else error_body = error.response[:body] status, title, detail, code = error_object_details(error_body, status_code) [transform_error_keys(error_body, status, title, detail, code)] end end |
.get_status_code(response) ⇒ Object
137 138 139 140 141 |
# File 'lib/lighthouse/service_exception.rb', line 137 def self.get_status_code(response) return response.status if response.respond_to?(:status) response[:status] if response.instance_of?(Hash) && response&.key?(:status) end |
.json_response?(response) ⇒ Boolean
143 144 145 146 |
# File 'lib/lighthouse/service_exception.rb', line 143 def self.json_response?(response) format = response_type(response) format&.include? 'application/json' end |
.log_to_rails_logger(service_name, options) ⇒ Object
130 131 132 133 134 135 |
# File 'lib/lighthouse/service_exception.rb', line 130 def self.log_to_rails_logger(service_name, ) Rails.logger.error( service_name, ) end |
.missing_http_status_server_error(error) ⇒ Object
43 44 45 46 47 48 49 50 51 |
# File 'lib/lighthouse/service_exception.rb', line 43 def self.missing_http_status_server_error(error) if error.instance_of?(Faraday::TimeoutError) # we've seen this Faraday error in production so we're adding this to categorize it Common::Exceptions::Timeout.new(errors: [{ title: error.class, detail: error. }]) else # we're not sure if there are other uncategorized errors, so we're adding this to catch any Common::Exceptions::ServiceError.new(errors: [{ title: error.class, detail: error. }]) end end |
.response_type(response) ⇒ Object
148 149 150 151 152 |
# File 'lib/lighthouse/service_exception.rb', line 148 def self.response_type(response) return response[:headers]['content-type'] if response[:headers] response.headers['content-type'] if response.respond_to?(:headers) end |
.send_error(error, service_name, lighthouse_client_id, url, options = {}) ⇒ Object
sends error logs to sentry that contains the client id and url that the consumer was trying call raises an error based off of what the response status was formats the Lighthouse exception for the controller ExceptionHandling to report out to the consumer
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/lighthouse/service_exception.rb', line 31 def self.send_error(error, service_name, lighthouse_client_id, url, = {}) send_error_logs(error, service_name, lighthouse_client_id, url, ) return error unless error.respond_to?(:response) response = error.response status_code = get_status_code(response) raise missing_http_status_server_error(error) unless status_code errors = get_errors_from_response(error, status_code) if json_response?(response) raise error_class(status_code).new(errors:) end |
.send_error_logs(error, service_name, lighthouse_client_id, url, options = {}) ⇒ Object
log errors
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/lighthouse/service_exception.rb', line 104 def self.send_error_logs(error, service_name, lighthouse_client_id, url, = {}) = { url:, lighthouse_client_id: } if error.respond_to?(:response) && error.response.present? [:status] = error.response[:status] [:body] = error.response[:body] else [:message] = error. [:backtrace] = error.backtrace end [:invoker] = [:invoker] if [:invoker] log_to_rails_logger(service_name, ) extra_context = Sentry.set_extras( message: error., url:, client_id: lighthouse_client_id ) = Sentry.(external_service: service_name) log_exception_to_sentry(error, extra_context, ) end |
.transform_error_keys(error_body, status, title, detail, code) ⇒ Object
transform error hash keys into symbols for controller ExceptionHandling class
97 98 99 100 101 |
# File 'lib/lighthouse/service_exception.rb', line 97 def self.transform_error_keys(error_body, status, title, detail, code) error_body .merge({ status:, code:, title:, detail: }) .transform_keys(&:to_sym) end |