Files
fizzy/app/controllers/commands_controller.rb
T
Jorge Manrubia 179ae45bf3 Show command errors
I went with placing htis logic at the command level since it plays well with the composite structure, where you don't know whether you are handling one command or many commands, and you want to aggregate all the errors. I didn't leverage the existing support with rails' model errors because that customizing those message is cumbersome (either i18n or using custom validation logic for everything).
2025-06-30 23:10:39 +02:00

75 lines
2.1 KiB
Ruby

class CommandsController < ApplicationController
def index
@commands = Current.user.commands.root.order(created_at: :desc).limit(20).reverse
end
def create
command = parse_command(params[:command])
if command.valid?
if confirmed?(command)
command.save!
result = command.execute
respond_with_execution_result(result)
else
respond_with_needs_confirmation(command)
end
else
respond_with_error(command)
end
end
private
def parse_command(string)
command_parser.parse(string)
end
def command_parser
@command_parser ||= Command::Parser.new(parsing_context)
end
def parsing_context
@parsing_context ||= Command::Parser::Context.new(Current.user, url: request.referrer)
end
def confirmed?(command)
!command.needs_confirmation? || params[:confirmed].present?
end
def respond_with_execution_result(result)
case result
when Array
respond_with_composite_response(result)
when Command::Result::Redirection
redirect_to result.url
when Command::Result::InsightResponse
respond_with_insight_response(result)
else
redirect_back_or_to root_path
end
end
def respond_with_needs_confirmation(command)
redirection_url = command.context.url unless command.context.url == parsing_context.url
render json: { confirmation: command.confirmation_prompt, redirect_to: redirection_url }, status: :conflict
end
def respond_with_composite_response(results)
json = results.map(&:as_json).grep(Hash).reduce({}, :merge)
if json.empty?
redirect_back_or_to root_path
else
render json: json, status: :accepted
end
end
def respond_with_insight_response(chat_response)
render json: { message: chat_response.content }, status: :accepted
end
def respond_with_error(command)
error_message = command.error_messages.map { |msg| "- #{msg}\n" }.join
render json: { error: error_message, context_url: command.context.url }, status: :unprocessable_entity
end
end