Add handle_exception method to log errors during GenerationJob execution#310
Add handle_exception method to log errors during GenerationJob execution#310TheRealNeil wants to merge 1 commit intoactiveagents:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a missing class-level exception handler to the ActiveAgent::Rescue concern so ActiveAgent::GenerationJob#handle_exception_with_agent_class can invoke klass.handle_exception(exception) without raising NoMethodError during generate_later.
Changes:
- Add
ActiveAgent::Rescue.handle_exception(exception)as a class method. - Log exception class/message and the first 10 backtrace lines when called as a job-level fallback.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Rails.logger.error "[#{name}] #{exception.class}: #{exception.message}" | ||
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | ||
| end | ||
|
|
There was a problem hiding this comment.
handle_exception logs via Rails.logger, which bypasses the framework’s configurable logger (ActiveAgent::Base.logger / config.logger) and can also raise NameError if ActiveAgent is used without Rails loaded. Prefer logging through the agent/logger accessor (with a safe fallback) so custom logger configuration is respected.
| Rails.logger.error "[#{name}] #{exception.class}: #{exception.message}" | |
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | |
| end | |
| agent_logger.error "[#{name}] #{exception.class}: #{exception.message}" | |
| agent_logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | |
| end | |
| private | |
| # Returns the logger to use for class-level exception handling. | |
| # | |
| # Prefers the including class's logger, then ActiveAgent::Base.logger, | |
| # then Rails.logger if available, and finally falls back to a standard | |
| # Ruby Logger to $stderr. | |
| # | |
| # @return [#error] a logger-like object responding to `#error` | |
| def agent_logger | |
| if respond_to?(:logger) && (current_logger = logger) | |
| current_logger | |
| elsif defined?(ActiveAgent::Base) && | |
| ActiveAgent::Base.respond_to?(:logger) && | |
| (base_logger = ActiveAgent::Base.logger) | |
| base_logger | |
| elsif defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger | |
| Rails.logger | |
| else | |
| require "logger" | |
| @__active_agent_rescue_logger ||= Logger.new($stderr) | |
| end | |
| end |
| # @return [void] | ||
| def handle_exception(exception) | ||
| Rails.logger.error "[#{name}] #{exception.class}: #{exception.message}" | ||
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace |
There was a problem hiding this comment.
As written, this default handle_exception implementation will swallow the original exception (ActiveJob rescue_from considers it handled), which can cause GenerationJob failures to be silently marked successful and prevent job-level retries/discard logic from running. Consider re-raising after logging (or making the default behavior opt-in) so failures still surface to the job framework.
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | |
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | |
| raise exception |
| # Handles exceptions raised during GenerationJob execution. | ||
| # | ||
| # Called by GenerationJob#handle_exception_with_agent_class as a | ||
| # class-level fallback when no instance is available to handle the error. | ||
| # | ||
| # @param exception [Exception] the exception to handle | ||
| # @return [void] | ||
| def handle_exception(exception) | ||
| Rails.logger.error "[#{name}] #{exception.class}: #{exception.message}" | ||
| Rails.logger.error exception.backtrace&.first(10)&.join("\n") if exception.backtrace | ||
| end |
There was a problem hiding this comment.
This change introduces new behavior for background-job exception handling, but there doesn’t appear to be coverage asserting that GenerationJob calls the class-level handler and that the exception is logged/propagated as intended. Please add a test around GenerationJob#handle_exception_with_agent_class (and the default handle_exception) to prevent regressions.
Add missing
handle_exceptionclass method to Rescue concernFixes #306
Summary
handle_exceptionclass method toActiveAgent::Concerns::Rescueso thatGenerationJob#handle_exception_with_agent_classhas something to callRoot cause
GenerationJob#handle_exception_with_agent_classcallsklass.handle_exception(exception)(a class method), but theRescueconcern only defines instance methods. This causes aNoMethodErrorwhen a job-level exception is raised duringgenerate_later.Fix
Add a
handle_exceptionclass method to theRescueconcern'sclass_methodsblock. It logs the exception class, message, and first 10 lines of the backtrace viaRails.logger.error.Test plan
generate_laterand confirm it is logged rather than raisingNoMethodErrorrescue_frominstance-level handlers still work as expected