class Protobuf::Rpc::Middleware::ResponseEncoder
def call(env)
def call(env) @env = app.call(env) env.response = response env.encoded_response = encoded_response env end
def encoded_response
Encode the response wrapper to return to the client
def encoded_response log_debug { sign_message("Encoding response: #{response.inspect}") } env.encoded_response = wrapped_response.encode rescue => exception log_exception(exception) # Rescue encoding exceptions, re-wrap them as generic protobuf errors, # and re-raise them raise PbError.new(exception.message) end
def initialize(app)
def initialize(app) @app = app end
def log_signature
def log_signature env.signature || super end
def response
Prod the object to see if we can produce a proto object as a response
def response @response ||= begin candidate = env.response case when candidate.is_a?(Message) then validate!(candidate) when candidate.respond_to?(:to_proto) then validate!(candidate.to_proto) when candidate.respond_to?(:to_hash) then env.response_type.new(candidate.to_hash) when candidate.is_a?(PbError) then candidate else validate!(candidate) end end end
def validate!(candidate)
we expect so that deserialization on the client side works.
Ensure that the response candidate we've been given is of the type
def validate!(candidate) actual = candidate.class expected = env.response_type if expected != actual raise BadResponseProto.new("Expected response to be of type #{expected.name} but was #{actual.name}") end candidate end
def wrapped_response
it up so that it's in the correct spot in the response wrapper
The middleware stack returns either an error or response proto. Package
def wrapped_response if response.is_a?(Protobuf::Rpc::PbError) Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type) else Socketrpc::Response.new(:response_proto => response.encode) end end