class Aws::Plugins::ClientMetricsPlugin::Handler

def call(context)

def call(context)
  publisher = context.config.client_side_monitoring_publisher
  service_id = context.config.api.metadata["serviceId"]
  # serviceId not present in all versions, need a fallback
  service_id ||= _calculate_service_id(context)
  request_metrics = ClientSideMonitoring::RequestMetrics.new(
    service: service_id,
    operation: context.operation.name,
    client_id: context.config.client_side_monitoring_client_id,
    region: context.config.region,
    timestamp: DateTime.now.strftime('%Q').to_i,
  )
  context.metadata[:client_metrics] = request_metrics
  start_time = Aws::Util.monotonic_milliseconds
  final_error_retryable = false
  final_aws_exception = nil
  final_aws_exception_message = nil
  final_sdk_exception = nil
  final_sdk_exception_message = nil
  begin
    @handler.call(context)
  rescue StandardError => e
    # Handle SDK Exceptions
    inspector = Retries::ErrorInspector.new(
      e,
      context.http_response.status_code
    )
    if inspector.retryable?(context)
      final_error_retryable = true
    end
    if request_metrics.api_call_attempts.empty?
      attempt = request_metrics.build_call_attempt
      attempt.sdk_exception = e.class.to_s
      attempt.sdk_exception_msg = e.message
      request_metrics.add_call_attempt(attempt)
    elsif request_metrics.api_call_attempts.last.aws_exception.nil?
      # Handle exceptions during response handlers
      attempt = request_metrics.api_call_attempts.last
      attempt.sdk_exception = e.class.to_s
      attempt.sdk_exception_msg = e.message
    elsif !e.class.to_s.match(request_metrics.api_call_attempts.last.aws_exception)
      # Handle response handling exceptions that happened in addition to
      # an AWS exception
      attempt = request_metrics.api_call_attempts.last
      attempt.sdk_exception = e.class.to_s
      attempt.sdk_exception_msg = e.message
    end # Else we don't have an SDK exception and are done.
    final_attempt = request_metrics.api_call_attempts.last
    final_aws_exception = final_attempt.aws_exception
    final_aws_exception_message = final_attempt.aws_exception_msg
    final_sdk_exception = final_attempt.sdk_exception
    final_sdk_exception_message = final_attempt.sdk_exception_msg
    raise e
  ensure
    end_time = Aws::Util.monotonic_milliseconds
    complete_opts = {
      latency: end_time - start_time,
      attempt_count: context.retries + 1,
      user_agent: context.http_request.headers["user-agent"],
      final_error_retryable: final_error_retryable,
      final_http_status_code: context.http_response.status_code,
      final_aws_exception: final_aws_exception,
      final_aws_exception_message: final_aws_exception_message,
      final_sdk_exception: final_sdk_exception,
      final_sdk_exception_message: final_sdk_exception_message
    }
    if context.metadata[:redirect_region]
      complete_opts[:region] = context.metadata[:redirect_region]
    end
    request_metrics.api_call.complete(complete_opts)
    # Report the metrics by passing the complete RequestMetrics object
    if publisher
      publisher.publish(request_metrics)
    end # Else we drop all this on the floor.
  end
end