# frozen_string_literal: true module ConvenientService module Service module Plugins module RescuesResultUnhandledExceptions module Commands class FormatBacktrace < Support::Command ## # @!attribute [r] backtrace # @return [Array, nil] # attr_reader :backtrace ## # @!attribute [r] max_size # @return [Integer] # attr_reader :max_size ## # @param backtrace [Array, nil] # @param max_size [Integer] # @return [void] # # @internal # IMPORTANT: Sometimes `exception.backtrace` can be `nil`. # - https://blog.kalina.tech/2019/04/exception-without-backtrace-in-ruby.html # - https://github.com/jruby/jruby/issues/4467 # def initialize(backtrace:, max_size: Constants::DEFAULT_MAX_BACKTRACE_SIZE) @backtrace = backtrace.to_a @max_size = max_size end ## # @return [String] # # @note Exceptions formatting is inspired by RSpec. It has almost the same output (at least for RSpec 3). # # @example Backtrace with upto 10 lines. # # # /gem/lib/convenient_service/factories/services.rb:120:in `result' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `call' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `block in result' # # /gem/lib/convenient_service/dependencies/extractions/ruby_middleware/middleware/runner.rb:67:in `block (2 levels) in build_call_chain' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next' # # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `block in next' # # /gem/lib/convenient_service/support/cache.rb:110:in `fetch' # # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `next' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware.rb:73:in `call' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next' # # @example Backtrace with more than 10 lines. # # # /gem/lib/convenient_service/factories/services.rb:120:in `result' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `call' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `block in result' # # /gem/lib/convenient_service/dependencies/extractions/ruby_middleware/middleware/runner.rb:67:in `block (2 levels) in build_call_chain' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next' # # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `block in next' # # /gem/lib/convenient_service/support/cache.rb:110:in `fetch' # # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `next' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware.rb:73:in `call' # # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next' # # ... # def call message = backtrace.take(max_size).map { |line| Commands::FormatLine.call(line: line) }.join("\n") message << "\n# ..." if backtrace.size > max_size message end end end end end end end