Class: RailsMail::ExceptionParser

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_mail/exception_parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw) ⇒ ExceptionParser

Returns a new instance of ExceptionParser.



7
8
9
# File 'lib/rails_mail/exception_parser.rb', line 7

def initialize(raw)
  @raw = raw
end

Instance Attribute Details

#rawObject (readonly)

Returns the value of attribute raw.



5
6
7
# File 'lib/rails_mail/exception_parser.rb', line 5

def raw
  @raw
end

Instance Method Details

#extract_errorObject



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails_mail/exception_parser.rb', line 41

def extract_error
  # Look for the error line pattern - supporting both "A" and "An"
  error_match = @raw.match(/^A(?:n)? ([\w:]+) occurred in ([^:]+):\r\n\r\n\s+(.*?)\r\n\s+(.+?)\r\n/m)
  return {} unless error_match

  {
    type: error_match[1],
    location: error_match[2],
    message: error_match[3],
    backtrace_line: error_match[4]
  }
end

#extract_section(section_name) ⇒ Object



54
55
56
57
58
59
# File 'lib/rails_mail/exception_parser.rb', line 54

def extract_section(section_name)
  # Match the section header and everything until the next section header or end of string
  section_regex = /^-+\r\n#{Regexp.escape(section_name)}:\r\n-+\r\n(.*?)(?=\r\n-+\r\n|\z)/m
  match = @raw.match(section_regex)
  match ? match[1] : ""
end

#parseObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rails_mail/exception_parser.rb', line 16

def parse
  return {} unless @raw

  # Extract the error information from the first few lines
  error_info = extract_error

  # Extract sections using a more direct approach
  sections = {
    "Data" => extract_section("Data"),
    "Request" => extract_section("Request"),
    "Session" => extract_section("Session"),
    "Backtrace" => extract_section("Backtrace"),
    "Environment" => extract_section("Environment")
  }

  {
    error: error_info,
    data: parse_section_content(sections["Data"]),
    request: parse_section_content(sections["Request"]),
    session: parse_section_content(sections["Session"]),
    backtrace: parse_backtrace(sections["Backtrace"]),
    environment: parse_section_content(sections["Environment"])
  }
end

#parse_backtrace(content) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/rails_mail/exception_parser.rb', line 81

def parse_backtrace(content)
  return [] unless content && !content.empty?

  # Split by Windows-style line endings and extract non-empty lines
  lines = content.split("\r\n").map(&:strip).reject(&:empty?)
  # Filter out lines that start with * (which would be key-value pairs)
  lines.reject { |line| line.start_with?("*") }
end

#parse_section_content(content) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rails_mail/exception_parser.rb', line 61

def parse_section_content(content)
  return {} unless content && !content.empty?

  result = {}
  content.split("\r\n").each do |line|
    line = line.strip
    # Handle lines that start with * and have indentation
    if line.start_with?("*")
      # Remove the asterisk and any leading whitespace
      key_value = line.sub(/^\*\s*/, "").split(":", 2)
      if key_value.length == 2
        key = key_value[0].strip
        value = key_value[1].strip
        result[key] = value if key && !key.empty?
      end
    end
  end
  result
end

#valid_format?Boolean

Returns:

  • (Boolean)


11
12
13
14
# File 'lib/rails_mail/exception_parser.rb', line 11

def valid_format?
  return false unless @raw.present?
  @raw.include?("occurred in")
end