Module: ActiveRpc::Rpc::Concerns::RequestProcessor

Extended by:
ActiveSupport::Concern
Included in:
BaseController, ResourceController
Defined in:
lib/active_rpc/rpc/concerns/request_processor.rb

Overview

The RequestProcessor concern provides methods for processing gRPC requests with standardized error handling and parameter validation.

Examples:

def get_user
  process_request do
    validate_required_params!(request.message, :id)
    user = find_record(User, request.message.id)
    user.to_rpc_response
  end
end

Instance Method Summary collapse

Instance Method Details

#extract_params(payload, *param_names) ⇒ Object

Extract parameters from a request payload



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/active_rpc/rpc/concerns/request_processor.rb', line 45

def extract_params(payload, *param_names)
  # Step 1: Determine which fields to extract and get _fields metadata
  if payload.respond_to?(:_fields) && !payload._fields.empty?
    # Use _fields metadata (only top-level fields)
    fields_to_extract = payload._fields
      .reject { |path| path.include?('.') || path.include?('[') }
    # Pass the full _fields metadata for nested conversion
     = payload._fields
  elsif param_names.empty?
    # Extract all available fields from protobuf descriptor
    if payload.class.respond_to?(:descriptor)
      fields_to_extract = payload.class.descriptor.map(&:name)
    else
      fields_to_extract = []
    end
     = nil
  else
    # Extract only requested fields
    fields_to_extract = param_names.map(&:to_s)
     = nil
  end

  # Step 2: Extract the fields
  result = {}
  fields_to_extract.each do |field_name|
    field_sym = field_name.to_sym
    if payload.respond_to?(field_sym)
      field_value = payload.send(field_sym)
      # Pass the field path and metadata for nested conversion
      field_path = field_name
      result[field_sym] = convert_protobuf_to_ruby(field_value, field_path, )
    end
  end

  result
end

#process_requestObject

Process a request with a block, handling common errors



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/active_rpc/rpc/concerns/request_processor.rb', line 19

def process_request
  ActiveRecord::Base.transaction do
    yield
  end
rescue ActiveRecord::RecordNotFound => e
  fail!(:not_found, :record_not_found, e.message)
rescue ActiveRecord::RecordInvalid => e
  # For validation errors, we now return structured responses instead of failing
  # This should be handled by the individual controller methods
  raise e
rescue ArgumentError => e
  fail!(:invalid_argument, :invalid_request, e.message)
rescue UncaughtThrowError => e
  # Handle throw(:abort) from callbacks
  if e.tag == :abort
    fail!(:aborted, :operation_aborted, "Operation aborted")
  else
    # Re-raise if it's not an :abort throw
    raise e
  end
rescue StandardError => e
  Rails.logger.error("Error processing request: #{e.message}\n#{e.backtrace.join("\n")}")
  fail!(:internal, :unexpected_error, "An unexpected error occurred")
end