Class: Otto::RouteHandlers::ClassMethodHandler

Inherits:
BaseHandler
  • Object
show all
Defined in:
lib/otto/route_handlers.rb

Overview

Handler for class methods (existing Otto pattern) Maintains backward compatibility for Controller.action patterns

Instance Attribute Summary

Attributes inherited from BaseHandler

#otto_instance, #route_definition

Instance Method Summary collapse

Methods inherited from BaseHandler

#initialize

Constructor Details

This class inherits a constructor from Otto::RouteHandlers::BaseHandler

Instance Method Details

#call(env, extra_params = {}) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/otto/route_handlers.rb', line 268

def call(env, extra_params = {})
  req = Rack::Request.new(env)
  res = Rack::Response.new

  begin
    # Apply the same extensions and processing as original Route#call
    setup_request_response(req, res, env, extra_params)

    # Call class method directly (existing Otto behavior)
    result = target_class.send(route_definition.method_name, req, res)

    # Only handle response if response_type is not default
    if route_definition.response_type != 'default'
      handle_response(result, res, {
        class: target_class,
        request: req
      })
    end

  rescue => e
    # Error handling - return 500 with proper headers like main Otto error handler
    error_id = SecureRandom.hex(8)
    Otto.logger.error "[#{error_id}] #{e.class}: #{e.message}"
    Otto.logger.debug "[#{error_id}] Backtrace: #{e.backtrace.join("\n")}" if Otto.debug

    res.status = 500

    # Content negotiation for error response
    accept_header = env['HTTP_ACCEPT'].to_s
    if accept_header.include?('application/json')
      res.headers['content-type'] = 'application/json'
      error_data = if Otto.env?(:dev, :development)
        {
          error: 'Internal Server Error',
          message: 'Server error occurred. Check logs for details.',
          error_id: error_id,
        }
      else
        {
          error: 'Internal Server Error',
          message: 'An error occurred. Please try again later.',
        }
      end
      res.write JSON.generate(error_data)
    else
      res.headers['content-type'] = 'text/plain'
      if Otto.env?(:dev, :development)
        res.write "Server error (ID: #{error_id}). Check logs for details."
      else
        res.write "An error occurred. Please try again later."
      end
    end

    # Add security headers if available
    if otto_instance&.respond_to?(:security_config) && otto_instance.security_config
      otto_instance.security_config.security_headers.each do |header, value|
        res.headers[header] = value
      end
    end
  end

  finalize_response(res)
end