class Brpoplpush::RedisScript::LuaError

LuaError raised on errors in Lua scripts

@author Mikael Henriksson <mikael@mhenrixon.com>

Constants

CONTEXT_LINE_NUMBER
LIB_PATH
PATTERN

Reformats errors raised by redis representing failures while executing a lua script. The default errors have confusing messages and backtraces, and a type of RuntimeError. This class improves the message and modifies the backtrace to include the lua script itself in a reasonable way.

Attributes

content[R]
error[R]
file[R]

Public Class Methods

intercepts?(error) click to toggle source

Is this error one that should be reformatted?

@param error [StandardError] the original error raised by redis @return [Boolean] is this an error that should be reformatted?

# File lib/brpoplpush/redis_script/lua_error.rb, line 32
def self.intercepts?(error)
  PATTERN.match?(error.message)
end
new(error, script) click to toggle source

Initialize a new {LuaError} from an existing redis error, adjusting the message and backtrace in the process.

@param error [StandardError] the original error raised by redis @param script [Script] a DTO with information about the script

Calls superclass method
# File lib/brpoplpush/redis_script/lua_error.rb, line 42
def initialize(error, script)
  @error        = error
  @file         = script.path
  @content      = script.source
  @backtrace    = @error.backtrace

  @error.message.match(PATTERN) do |regexp_match|
    line_number   = regexp_match[2].to_i
    message       = regexp_match[3]
    error_context = generate_error_context(content, line_number)

    super("#{message}\n\n#{error_context}\n\n")
    set_backtrace(generate_backtrace(file, line_number))
  end
end

Private Instance Methods

backtrace_before_entering_gem(backtrace) click to toggle source

:nocov:

# File lib/brpoplpush/redis_script/lua_error.rb, line 85
def backtrace_before_entering_gem(backtrace)
  backtrace.reverse.take_while { |line| !line_from_gem(line) }.reverse
end
generate_backtrace(file, line_number) click to toggle source

:nocov:

# File lib/brpoplpush/redis_script/lua_error.rb, line 75
def generate_backtrace(file, line_number)
  pre_gem                 = backtrace_before_entering_gem(@backtrace)
  index_of_first_gem_line = (@backtrace.size - pre_gem.size - 1)

  pre_gem.unshift(@backtrace[index_of_first_gem_line])
  pre_gem.unshift("#{file}:#{line_number}")
  pre_gem
end
generate_error_context(content, line_number) click to toggle source

:nocov:

# File lib/brpoplpush/redis_script/lua_error.rb, line 61
def generate_error_context(content, line_number)
  lines                 = content.lines.to_a
  beginning_line_number = [1, line_number - CONTEXT_LINE_NUMBER].max
  ending_line_number    = [lines.count, line_number + CONTEXT_LINE_NUMBER].min
  line_number_width     = ending_line_number.to_s.length

  (beginning_line_number..ending_line_number).map do |number|
    indicator = (number == line_number) ? "=>" : "  "
    formatted_number = format("%#{line_number_width}d", number)
    " #{indicator} #{formatted_number}: #{lines[number - 1]}"
  end.join.chomp
end
line_from_gem(line) click to toggle source

:nocov:

# File lib/brpoplpush/redis_script/lua_error.rb, line 90
def line_from_gem(line)
  line.split(":").first.include?(LIB_PATH)
end