Module: ExceptionHandling

Extended by:
ActiveSupport::Concern
Included in:
ApplicationController, SignIn::ApplicationController, SignIn::ServiceAccountApplicationController
Defined in:
app/controllers/concerns/exception_handling.rb

Constant Summary collapse

SKIP_SENTRY_EXCEPTION_TYPES =

In addition to Common::Exceptions::BackendServiceException that have sentry_type :none the following exceptions will also be skipped.

[
  Breakers::OutageException,
  JsonSchema::JsonApiMissingAttribute,
  Pundit::NotAuthorizedError
].freeze

Instance Method Summary collapse

Instance Method Details

#render_errors(va_exception) ⇒ Object (private)



62
63
64
65
66
67
68
69
# File 'app/controllers/concerns/exception_handling.rb', line 62

def render_errors(va_exception)
  case va_exception
  when JsonSchema::JsonApiMissingAttribute
    render json: va_exception.to_json_api, status: va_exception.code
  else
    render json: { errors: va_exception.errors }, status: va_exception.status_code
  end
end

#report_mapped_exception(exception, va_exception) ⇒ Object (private)



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/controllers/concerns/exception_handling.rb', line 81

def report_mapped_exception(exception, va_exception)
  extra = exception.respond_to?(:errors) ? { errors: exception.errors.map(&:to_h) } : {}
  # Add additional user specific context to the logs
  if exception.is_a?(Common::Exceptions::BackendServiceException) && current_user.present?
    extra[:icn] = current_user.icn
    extra[:mhv_correlation_id] = current_user.mhv_correlation_id
  end
  va_exception_info = { va_exception_errors: va_exception.errors.map(&:to_hash) }
  log_exception_to_sentry(exception, extra.merge(va_exception_info))

  # Because we are handling exceptions here and not re-raising, we need to set the error on the
  # Datadog span for it to be reported correctly. We also need to set it on the top-level
  # (Rack) span for errors to show up in the Datadog Error Tracking console.
  # Datadog does not support setting rich structured context on spans so we are ignoring
  # the extra va_exception and other context for now. We can set tags in Datadog as they are used
  # in Sentry, but tags are not suitable for complex objects.
  Datadog::Tracing.active_span&.set_error(exception)
  request.env[Datadog::Tracing::Contrib::Rack::Ext::RACK_ENV_REQUEST_SPAN]&.set_error(exception)
end

#report_original_exception(exception) ⇒ Object (private)



71
72
73
74
75
76
77
78
79
# File 'app/controllers/concerns/exception_handling.rb', line 71

def report_original_exception(exception)
  # report the original 'cause' of the exception when present
  if skip_sentry_exception?(exception)
    Rails.logger.error "#{exception.message}.", backtrace: exception.backtrace
  elsif exception.is_a?(Common::Exceptions::BackendServiceException) && exception.generic_error?
    # Warn about VA900 needing to be added to exception.en.yml
    log_message_to_sentry(exception.va900_warning, :warn, i18n_exception_hint: exception.va900_hint)
  end
end

#skip_sentry_exception?(exception) ⇒ Boolean (private)

Returns:

  • (Boolean)


25
26
27
28
29
# File 'app/controllers/concerns/exception_handling.rb', line 25

def skip_sentry_exception?(exception)
  return true if exception.class.in?(skip_sentry_exception_types)

  exception.respond_to?(:sentry_type) && !exception.log_to_sentry?
end

#skip_sentry_exception_typesObject (private)



21
22
23
# File 'app/controllers/concerns/exception_handling.rb', line 21

def skip_sentry_exception_types
  SKIP_SENTRY_EXCEPTION_TYPES
end